第九课 《类与对象》
第一部分:类与对象的必要了解的知识点:
什么是类:类是对具有相同属性(字段或者成员变量)和行为(法)的一组对象的抽象,对一类对象的统称。
什么是对象:对象就是每个类的具体化的实例,是现实世界客观存在的。如一两大众汽车,一本书等等。
类与对象的关系:简单的例子:我们做月饼的模子就是一个类,而通过这个模子可以做出月饼,那么在这个例子当中,类就是那个模子,而月饼就是那个对象,所以月饼就是一个实体,一个对象一个模子可以实例化无数个对象。总的来说:类相当于一个模板,对象是由模板产生的样本。一个类,可以产生无数的对象。声明一个类就是创建一个新的数据类型,而类在 Java 中属于引用类型, Java 使用关键字 class 来声明类
什么是面向过程:
面向过程其实是最为实际的一种思考方式,就算是面向对象的方法也是含有面向过程的思想。可以说面向过程是一种基础的方法。它考虑的是实际地实现。一般的面向过程是从上往下步步求精,所以面向过程最重要的是模块化的思想方法。对比面向过程,面向对象的方法主要是把事物给对象化,对象包括属性与行为。当程序规模不是很大时,面向过程的方法还会体现出一种优势。因为程序的流程很清楚,按着模块与函数的方法可以很好的组织。比如拿学生早上起来这件事说明面向过程,粗略的可以将过程拟为:
(1)起床
(2)穿衣
(3)洗脸刷牙
(4)去学校
而这4步就是一步一步地完成,它的顺序很重要,你只需要一个一个地实现就行了。而如果是用面向对象的方法的话,可能就只抽象出一个学生的类,它包括这四个方法,但是具体的顺序就不一定按照原来的顺序。
什么是面向对象:从现实世界中客观存在的事物(即对象)出发来构造软件系统,并在系统构造中尽可能运用人类的自然思维方式,强调直接以问题域(现实世界)中的事物为中心来思考问题,认识问题,并根据这些事物的本质特点,把它们抽象地表示为系统中的对象,作为系统的基本构成单位(而不是用一些与现实世界中的事物相关比较远,并且没有对应关系的其它概念来构造系统)。这可以使系统直接地映射问题域,保持问题域中事物及其相互关系的本来面貌。
面向对象与面向过程的区别在哪里:
面向对象与面向过程的区别
面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了;面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。
其实就是两句话,面向对象就是高度实物抽象化、面向过程就是自顶向下的编程!
对象:现实中任何事物都可以称之为对象,有自己的独特的特点。 属性是用来描述具体某个对象的特征。例如小明身高180,体重70千克,身高和体重就是属性。 面向对象的思想就是把一切事物都看成对象,而对象一般都是由属性和方法组成。 属性属于对象静态的一面,用来形容对象的一些特性。 方法属于对象动态的一面,例如,小明会跑,会说话。跑,说话这些行为就是对象的方法! 类:具有同种属性的对象称为类,。比如,“人”就是一类,其中的人名比如小明,小红等都是对象。类相当于一个模板,他定义了它所包含的全体对象的公共特征和功能,对象是类的实例化。所以我们一般在做程序的时候一般都不用类名的,比如我们在叫小明的时候,不会喊“人,你干嘛呢!”而是说的是“小明,你在干嘛呢!” 面向对象有三大特性:封装性,继承性和多态性
面向过程:
优点是性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源。而Linux\Unix等一般采用面向过程开发,性能是最重要的因素。缺点是没有面向对象易维护,易复用,易扩展。可维护性差,不易修改。
面向对象:
优点是易维护,易复用,易扩展。由于面向对象由封装,继承,多态性的特性,可以设计出耦合度低的系统,使系统更加灵活,更加易于维护。 缺点是性能比面向过程低。
本人对与面向对象与面向过程的理解:
面向对象:是看待问题,解决问题的一种思维方式,重点在于找到一个能够解决问题的实体,
然后委托给实体去解决问题。
面向过程:是看待问题,解决问题的一种思维方式,重点在于问题是怎么一步步的解决的,
然后亲力亲为的解决问题。
自己深入的去理解一下上面的8——11的四句话,这个非常重要。
什么是成员变量:1 类中的方法外 2 对象存在他存在 对象消失他消失 3 有默认的初始值
什么是成员方法:在某些情况下,我们要需要定义成员方法(简称方法)。比如人类:除了有一些属性外( 年龄,姓名…),我们人类还有一 些行为比如:可以说话、跑步…,通过学习,还可以做算术题。这时就要用成员方法才能完成。成员方法可以提高代码重复利用率,方便供其他用户使用。
形参列表:表示成员方法的输入
返回数据类型:表示成员方法输出, void 表示没有返回值
方法主体:表示为了实现某一功能代码块
return 语句不是必须的。return 不需要返回语句
局部变量与全局变量的区别:
1、作用域不同:全局变量的作用域为整个程序,而局部变量的作用域为当前函数或循环等。
2、内存存储方式不同:全局变量存储在全局数据区中,局部变量存储在栈区。
3、生命期不同:全局变量的生命期和主程序一样,随程序的销毁而销毁,局部变量在函数内部或循环内部,随函数的退出或循环退出就不存在了。
4、使用方式不同:全局变量在声明后程序的各个部分都可以用到,但是局部变量只能在局部使用。函数内部会优先使用局部变量再使用全局变量
如何定义一个标准的类:1 属性 成员变量 2 方法 用成员方法 3 无惨构造 4 有参构造 5 get set 方法 get 得到 set 设置 6 tostring 方法
方法的重写与重载的区别:
重写体现了Java优越性,重写是建立在继承关系上,它使语言结构更加丰富。在Java中的继承中,子类既可以隐藏和访问父类的方法,也可以覆盖继承父类的方法。
在Java中覆盖继承父类的方法就是通过方法的重写来实现的。所谓方法的重写是指子类中的方法与父类中继承的方法有完全相同的返回值类型、方法名、参数个数以及参数类型。
这样,就可以实现对父类方法的覆盖。如果子类将父类中的方法重写了,调用的时候肯定是调用被重写过的方法,那么如果现在一定要调用父类中的方法该怎么办呢?-----super关键字(被覆盖的是实例方法)/父类类名(被覆盖的是类方法)作为调用者。
此时,通过使用super关键就可以实现这个功能,super关键字可以从子类访问父类中的内容,如果要访问被重写过的方法,使用“super.方法名(参数列表)”的形式调用。
如果要使用super关键字不一定非要在方法重写之后使用,也可以明确地表示某个方法是从父类中继承而来的。使用super只是更加明确的说,要从父类中查找,就不在子类查找了。
二、重写规则
在重写方法时,需要遵循以下的规则: 两同两小一大
方法名相同,参数列表相同
子类返回值类型<=父类方法返回值类型
子类方法声明抛出异常类<=父类方法声明抛出异常类
子类方法的访问权限>=父类方法的访问权限。
虽然每个重载方法可以有不同的返回类型,但返回类型并不足以区分所使用的是哪个方法。即不能依据返回值类型判断使用的是哪一个方法
例子:对于 int f(){}和 void f(){}两个方法,如果是这样调用:int result=f();系统可以识别是调用返回值类型的方法;但java调用方法时可以忽略返回值,如果这样调用f();就不能判断调用的是哪个方法。因此,Java里不能使用方法返回值类型作为区分方法重载的依据。只能通过不同的形参列表
当Java调用一个重载方法时,参数与调用参数匹配的方法被执行。在使用重载要注意以下的几点:
1.在使用重载时只能通过不同的参数列表,必须具有不同的参数列表。
4.可以有不同的返回类型,只要参数列表不同,方法名相同就可以了。
5.可以有不同的访问修饰符。
三、方法重载(Overloading)
方法重载是让类以统一的方式处理不同类型数据的一种手段。调用方法时通过传递给它们的不同个数和类型的参数来决定具体使用哪个方法,这就是多态性。
所谓方法重载是指在一个类中,多个方法的方法名相同,但是参数列表不同。参数列表不同指的是参数个数、参数类型或者参数的顺序不同。
方法的重载在实际应用中也会经常用到。不仅是一般的方法,构造方法也可以重载。
在方法重载时,方法之间需要存在一定的联系,因为这样可以提高程序的可读性,一般只重载功能相似的方法。
重载是指我们可以定义一些名称相同的方法,通过定义不同的参数来区分这些方法,然后再调用时,Java虚拟机就会根据不同的参数列表来选择合适的方法执行
。也就是说,当一个重载方法被调用时,Java用参数的类型或个数来决定实际调用的重载方法。因此,每个重载方法的参数的类型或个数必须是不同。
第二部分代码实操将知识讲透:
案例一
package com.D1; public class People { /* * private 私有的 * 属性用成员变量去表示 */ //姓名 public String name; //年龄 public int age; //性别 public String sex; public int height=123; }
/* * 行为用方法去表示 */ //吃饭 public void eat(){ System.out.println("L LOVE SEE you eat english"); } /** * 方法名称 */ //睡觉 public void sleep(){ System.out.println("睡觉觉哦23"); } public void learn(){ System.out.println("学习使你快乐45"); } public void weep(){ System.out.println("weep weep hellow neeas very see you me"); }
package com.D1; import java.util.*; public class PeopleTest { /** * @param args */ public static void main(String[] args) { //得到People类的一个对象 People d = new People(); //获取对象的成员变量,在没有赋值的情况下,系统会提供一个默认值null,int类型为0 // System.out.println(); 打印输出语句 System.out.println(d.name); System.out.println(d.age); System.out.println(d.sex); //因为我身高设置了默认值 System.out.println(d.height+"cm"); System.out.println(d.weight+"kg"); //获取对象的行为 d.eat(); d.sleep(); d.weep(); System.out.println("================在没有设置值的情况下=============="); } }
//设置对象的成员变量值 //设置对象的姓名 d.name = "小明"; //设置对象的年龄 d.age = 19; //设置对象的性别 d.sex = "男"; System.out.println(d.name); System.out.println(d.age); System.out.println(d.sex); System.out.println("在设置了值的情况下"); People e = new People(); e.eat(); e.sleep(); e.name = "蛋蛋"; e.age = 10; e.sex = "女"; System.out.println(e.name); System.out.println(e.age); System.out.println(e.sex);
案例二:
package com.D1; public class Student { String name; int age; //无参构造 public Student() { super(); // TODO Auto-generated constructor stub } //有参构造 public Student(String name, int age) { super(); this.name = name; this.age = age; } //get and set 方法 /** * @return the name */ public String getName() { return name; } /** * @param name the name to set */ public void setName(String name) { this.name = name; } /** * @return the age */ public int getAge() { return age; } /** * @param age the age to set */ public void setAge(int age) { this.age = age; } /** * 定义的方法 */ public void study(){ System.out.println("好好学习,天天向上"); } public void doHomeWork(){ System.out.println("键盘敲烂,月薪过万"); } public void play(){ System.out.println("玩玩游戏,人生百拜拜"); } /** * toString */ @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } }
package com.D1; /** * 学生测试类 */ public class StudentTest { public static void main(String[] args) { Student s = new Student(); System.out.println(s); //使用对象成员变量 System.out.println(s.name+","+s.age); System.out.println("创建第一个对象"); s.name = "湖北"; s.age = 28; //调用对象的方法 System.out.println("=============================================="); s.study(); s.doHomeWork(); s.play(); System.out.println("------------------------------------------"); System.out.println(s.name+","+s.age); //创建第二个对象 Student s1 = new Student(); s1.name="湖南"; s1.age = 30; //调用的方法名称 s1.study(); System.out.println(s1.name+","+s1.age); //创建第三个对象 Student s2 = new Student(); s2.name="河北"; s2.age = 30; System.out.println(s2.name+","+s2.age); System.out.println(s1==s2); //创建第四个对象 Student s3 = new Student(); s3.name="河南"; s3.age = 20; System.out.println(s3.name+","+s3.age); System.out.println(s1==s3); } }
案例三——定义一个标准的类:
package com.D2; /** * 定义一个标准类 */ public class Car{ private String brand;//汽车品牌 private String color;//颜色 private double weight;//载重 /* * 定义无参数的构造方法 */ public Car() { super(); // TODO Auto-generated constructor stub } /* * 定义一个有参数的构造方法 */ public Car(String brand, String color, double weight) { super(); this.brand = brand; this.color = color; this.weight = weight; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public double getWeight() { return weight; } public void setWeight(double weight) { this.weight = weight; } @Override public String toString() { return "Car [brand=" + brand + ", color=" + color + ", weight=" + weight + "]"; } }
案例四:方法的重载
package com.D2; /** * 方法的重载:方法相同,参数不同 * 提高了类中定义方法的灵活性 * @author Administrator * */ public class OverLoad { //定义一个方法求两个数的和 public double sum(double a,double b){ return a+b; } //定义一个方法求三个数的和 public double sum(double a,double b,double c){ return a+b+c; } //定义一个方法求四个数的和 public double sum(double a,int b,double c,int d){ return a+b+c+d; } }
案例五
package com.D2; public class Student { //成员变量 private String name; private int age; public Student() { super(); // TODO Auto-generated constructor stub } public Student(String name, int age) { super(); this.name = name; this.age = age; } /** * @return the name */ public String getName() { return name; } /** * @param name the name to set */ public void setName(String name) { this.name = name; } /** * @return the age */ public int getAge() { return age; } /** * @param age the age to set */ public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } }
package com.D2; public class StudentTest { /** * 代码test */ /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Student stu = new Student(); //设置学生的姓名 // stu.name = "maomao"; stu.setName("兴旺里路mao mao mao"); //获取学生的姓名 System.out.println(stu.getName()); //设置学生的年龄 stu.setAge(17); System.out.println(stu.getAge()); Student stu1 = new Student(); stu1.setName("天行健,举哀天下名"); System.out.println(stu1.getName()); //设置学生的年龄 stu1.setAge(34); System.out.println(stu1.getAge()); Student stu2 = new Student(); stu1.setName("生在盛世,当不服盛世"); System.out.println(stu1.getName()); //设置学生的年龄 stu1.setAge(23); System.out.println(stu1.getAge()); } }