面向对象之理解
面向对象之理解
1.简单举例:
我们可以看到一个超市有收银员,采购员,配货员等.
收银员之间:有不同的姓名,年龄,工号等,但有相同的行为方法,即扫描货物,收钱,找钱等.
采购员之间:有不同的姓名,年龄,工号等,但有相同的行为方法,即统计缺货数量,进行采购行为等.
配货员之间:有不同的姓名,年龄,工号等,但有相同的行为方法,即查明缺货位置,进行配货行为等.
大家一起合作使得超市运作起来
面向对象其实就如同面向一个个超市的具体员工
2.类和对象的概念
Java语言是用来描述现实世界事务的,最基本的单位是:类,类是对象的抽象.在java中代码都是我们用键盘敲的,那么写在我们代码里的,也就是我们定义,创建的,因为他们是你码的.
对象就如同超市具体工作的每个员工,
类就如同一个群体,如收银员这个群体,我们叫他收银员类,
我们定义这类收银员都应该有姓名,年龄,工号等属性,我们在定义时称其为成员变量.
我们收银员定义这类收银员都应该做某些规定的行为方法,我们在定义时称其为成员方法.
因此我们在定义类的时候,可以包括成员变量,成员方法.(可以定义什么都没有得类,但是这很浪费感情).
a:类:是一组相关的属性(成员变量)和行为(成员方法)的集合.)类是具有相同特征(属性)和行为(功能)的一类事物的抽象.
b:对象:是该类事物的具体体现.
3.类和对象的使用
(1)类的成员
定义类其实就是定义类的成员(所属关系是直接属于类的均称为成员,如成员变量、成员方法)
a:成员变量 在类中,方法外。
b:成员方法
(2)如何使用对象
创建对象的格式:类名 对象名 = new 类名();
Car c = new Car();// c是类类型(引用数据类型)的变量。c指向了一个具体的Car类型的对象。栈里面存类的引用c(地址值),堆里放对象.
a:调用成员变量:对象名.变量名
b:调用成员方法:对象名.方法名(...)
c:匿名对象应用场景:
a:调用方法,适用调用一次的时候。
new 类名(...).成员变量
new 类名(...).成员方法
b:匿名对象可以作为实际参数传递(地址值)
注意:调用多次的时候,不适合。匿名对象调用完毕就是垃圾。可以被垃圾回收器回收。
任何事物均可以定义成类,创建对象,属于引用类型而对象的引用变量是一个普通变量,通常是定义在方法中的局部变量,位于栈中。其存储的值是堆内存中某个对象的地址。
4.数据初始化--构造方法
(1)构造方法
构造方法是正常开发中不可或缺的一部分,是语法上必须存在的。
(2)构造方法存在的意义
a.用来创建实例对象的方法。没有构造方法是不能创建对象的,
b.创建对象时,完成对应逻辑,最常用的逻辑为创建对象的同时直接为成员变量赋值,无需再在对象产生后再赋值。
(3)构造方法格式特点
a:方法名与类名相同(大小也要与类名一致)
b:没有返回值类型,连void都没有
c:构造方法中可以出现return。用于方法结束。
public 类名(参数类型 参数1,参数类型 参数2){
//创建对象时要执行的逻辑,经常为为成员变量赋值
}
(4)构造方法的调用格式:
new 构造方法(参数);
//调用构造方法,创建对象
Person p = new Person("mm",2000);
(5)构造方法注意事项
a:构造方法是必须存在的,如果没有手动给出构造方法,Java会自动为我们补齐一个空参的构造方法。这个过程我们是看不到的
b:如果手动给出了构造方法,java则不会再自动补齐任何构造。
(3)有参无参构造
无参构造Public 类名() {}
有参构造public Student(String name,int age){
this.name = name;
This.age = age;
}
备注:多个构造方法由重载的方式共同存在,根据参数的不同而调用。
5.面向对象特征
封装(encapsulation) 继承(inheritance) 多态(polymorphism)
(1)封装
是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。便于调用者的理解与使用,只需要关注功能
封装是相对而言的,不同的权限修饰符,使得有不同的访问权限,因此访问权限不同,使得隐藏对象的属性和实现细节不同,封装程度不同.另外方法,类,都是封装的体现..(不能说封装就是私有.)
a.封装好处
隐藏实现细节,提供公共的访问方式
提高了代码的复用性
提高安全性。
b.封装原则
将不需要对外提供的内容都隐藏起来。
把属性隐藏,提供公共方法对其访问。
c.常用private关键字封装
1) 特点
是一个权限修饰符
可以修饰成员变量和成员方法
被其修饰的成员只能在本类中被访问
2)private的应用
把成员变量用private修饰
提供对应的getXxx()和setXxx()方法(提供公共的访问方式)
(2)继承
让类与类之间产生关系,子父类关系.
子类也叫派生类
父类也叫基类,超类.
父类:定义了该类型子类均应该具备的成员变量与功能方法.我们在完成一个庞大项目体系的时候,设计期间都是将共性的内容向上抽取出,后续实现过程是从父类开始“向下”扩展的。
使用extends关键字完成继承关系。
1)继承的好处和弊端
继承的好处
提高了代码的复用性
提高了代码的维护性(父类增加属性,子类也有了属性)
让类与类之间产生了关系,是多态的前提
继承的弊端
类的耦合性增强了.子父类联系紧密,父类变化,子类变化
2)Java中的继承特点
a.类与类:继承关系,只能单继承,可以多层继承。
b.类与接口:实现关系,可以单实现,也可以多实现。
c.接口与接口:继承关系,可以单继承,也可以多继承。
3)使用继承
面向对象描述现实世界,能用语言描述为:我是你的一种,才应该写成继承.
4)继承的注意事项
a:子类只能继承父类所有非私有的成员(继承后直接调用)
b:子类不能继承父类的构造方法,但是通过super(马上讲)关键字去访问父类构造方法。自己是自己的构造方法,给自己初始化值的.
c:不要为了部分功能而去继承
如果有两个类A,B。只有他们符合A是B的一种,或者B是A的一种,就可以考虑使用继承。
注意:所有的类都直接或间接继承自Object,所以如果没有继承其他类,则默认继承Object类。即Object是所有类的父类(或超类)
Animal a = new Animal();
Syste.out.println(a); // Animal@1506bde8
Syste.out.println(a.toString());//Animal@1506bde8
输出语句直接打印对象,默认调用了该对象的toString() .Object类中的toString()默认打印的是对象的地址值,但是这样做事没有意义的.所以子类一般都会重写toString()
即:Public String toStrnig() {
Return “我是动物”
}。
5)继承中成员变量的关系
子父类出现不同名的变量可以输出;
子父类出现同名变量时,就近原则,
6)继承中构造方法的关系
1. 每个类,系统都会默认给一个 空参构造, 如果我们自己定义了构造方法,系统就不给了.
2. 子类的所有构造方法的第一行,默认都有一个super(),用于子类对象访问父类数据前,对父类数据进行初始化.
3. Object类是所有类的父类,它里边只有一个空参构造.所以会默认访问父类的空参,而不是带参构造.
4.父类没有空参构造的解决办法:
解决方案一: 通过super(参数)的形式,去访问父类的带参构造.
解决方案二: 通过this(参数)的形式,去访问本类的其他构造;
7)父类对象空间优于子类对象产生
在每次创建子类对象时,我们均会先创建父类对象,再创建其子类对象本身。目的在于子类对象中包含了其对应的父类对象空间,便可以包含其父类对象的成员,代码体现在子类的构造方法调用时,一定先调用父类的构造方法。
class Son extends Father {
public Son() {
//隐藏super();
System.out.println("Son空参构造");
}
public Son(String name,int age) {
//隐藏super();
System.out.println("Son有参构造");
}
(3)多态
概述:同一事物在不同时刻表现出来的不同状态(形态)
1)多态前提
a.必须有子父类(继承)关系或者类实现接口关系。
b:要有方法重写。
c:要有父类引用指向子类对象。
2)多态中的成员访问特点之成员变量
a.成员变量:编译看左边(父类),运行看左边(父类)。
b.成员方法:编译看左边(父类),运行看右边(子类)。动态绑定,如果父类中没有该方法,编译时不通过的
c.静态方:编译看左边(父类),运行看左边(父类)。
3)多态中向上转型和向下转型
a.向上转型:Person p = new SuperMan();(父类引用指向子类对象)(SuperMan()提升为了Person类型),
b.向下转型:SuperMan sm = (SuperMan)p;向下转型(如同强制类型转换),一定要先向上转型才有向下转型
4)多态的好处和弊端
a.多态的好处
提高了代码的维护性(继承保证)
提高了代码的扩展性(由多态保证)
可以当作形式参数,可以接收任意子类对象,调用成员方法时,运行看子类对象的方法
b.多态的弊端:不能使用子类的特有属性和行为。
5)多态的使用场景
a.成员变量赋值、局部变量赋值 animal = new Cat();
b.方法传参(最常用最能体现出多态优点的应用)(方法形参父类类型,可以接受任意的子类对象)
c.返回返回值,(返回什么类型声明类型接受)
6)instanceof关键字
我们可以通过instanceof关键字来判断某个对象是否属于某种数据类型。如学生的对象属于学生类,学生的对象也属于人类。
通常用于判断多态后的父类引用到底指向的是哪种子类类型。
使用格式: 判断前面的对象是不是这个数据类型
boolean b = 对象 instanceof 数据类型
注意:当对象判断的类型是该类型本身或者该类型的父类型时,均返回true
完全无关的两个类型无法判断(报错,编译不通过),
小结:
定义工作的群体---类,类的成员有成员变量,成员方法.
通过类创建对象:Cat c = new Cat();其中对象的实体存在堆里,对象名c存储了实体所存储的地址值,对象名c是属于类名类型即:Cat类型.而c是由new Cat()赋值过来的,则new Cat()存储的是地址值,并创建了对象实体,其实这个就是匿名对象.
进行调用即是:c.name = "加菲";即是通过地址值找到name,然后给name赋值.相当于 地址值.name = "加菲",地址值又可以写成new Cat(),即 new Cat().name = "加菲";
构造方法是用来对属性进行初始化的,:Cat c = new Cat();则是通过空参构造创建对象的,Cat c = new Cat("加菲",3);是通过有参构造创建对象的.
在创建对象时要初始化值,因此在类,系统默认有空参构造,建议空参有参都写上,在继承中,子类构造方法第一个语句是super(),你在子类中不写构造方法,也可以通过父类构造方法进行初始化.
下面有点套路:私有化成员变量--构造方法--成员方法(包括对私有化的公共访问方式).
整个面向对象有封装-继承-多态三个特点.这些特点代表可以这么用.
Father f = new Son();
f是Father类型的值,父类型的引用(地址值),指向子类对象.
public void method(Father f){....}
在调用参数时用对象时method(new Son()),其实是将这个匿名子类对象的地址值赋值给Father类型的f,就是父类引用指向子类对象.
a:类:是一组相关的属性(成员变量)和行为(成员方法)的集合. 类是具有相同特征(属性)和行为(功能)的一类事物的抽象。
b:对象:是该类事物的具体体