面向对象之继承
不存在继承有什么问题:
1:如果没有继承,出现类和类的关系无法描述
2:如果没有继承,类和类之间有关系会出现类和类的描述代码的重复。
继承能够解决的问题
1:描述类和类之间的关系
2:降低类和类之间的重复代码
总结:
1:降低对象和对象之间的代码重复使用静态变量
2:降低类和类之间的代码重复使用就继承
Super:
super关键字作用
1:主要存在于子类方法中,用于指向子类对象中父类对象。
2:访问父类的属性
3:访问父类的函数
4:访问父类的构造函数
super要注意的问题
this和super很像,this指向的是当前对象的调用,super指向的是当前调用对象的父类。
1:Demo类被加载,执行main方法,Son.class加载,发现有父类Father类,于是Father类也加载进内存。
2:类加载完毕,创建对象,父类的构造方法会被调用(默认自动无参),然后执行子类相应构造
3:创建了一个子类对象,该子类对象还包含了一个父类对象。该父类对象在子类对象内部。
子类的构造函数默认第一行会默认调用父类无参的构造函数,隐式语句super();
1:父类无参构造函数不存在,编译报错。
2:如果显式调用父类构造函数,编译器自动添加的调用父类无参数的构造就消失
3:构造函数间的调用只能放在第一行,只能调用一次。
super问题
1.如果开发者自定义了一个类,没有显示的进行类的继承,那么该类中成员函数是否可以使用super关健健字?
可以使用,继承了Object类,Object类是所有类的父类。
多态:
图示:
多态体现:
父类引用变量指向了子类的对象
父类引用也可以接受自己的子类对象
多态前提:
类与类之间有关系,继承或者实现
多态弊端:
提高扩展性,但是只能使用父类引用指向父类成员。
多态特点:
非静态
编译时期,参考引用型变量所属的类是否有调用的方法,如果有编译通过。没有编译失败
运行时期,参考对象所属类中是否有调用的方法。
总之成员函数在多态调用时,编译看左边,运行看右边。
在多态中,成员变量的特点,无论编译和运行参考左边(引用型变量所属的类)。
在多态中,静态成员函数特点,无论编译和运行都参考左边
抽象类和接口的区别
含有abstract修饰符的class即为抽象类,abstract 类不能创建的实例对象。含有abstract方法的类必须定义为abstract class,abstract class类中的方法不必是抽象的。abstract class类中定义抽象方法必须在具体(Concrete)子类中实现,所以,不能有抽象构造方法或抽象静态方法。如果的子类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为abstract类型。
接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final。
重写(Override)
在继承中,子类可以定义和父类相同的名称且参数列表一致的函数,将这种函数称之为函数的重写.
前提:
1:必须要有继承关系
特点:
1. 当子类重写了父类的函数,那么子类的对象如果调用该函数,一定调用的是重写过后的函数。
可以通过super关键字进行父类的重写函数的调用。
2. 继承可以使得子类增强父类的方法
细节:
1. 函数名必须相同
2. 参数列表必须相同
3. 子类重写父类的函数的时候,函数的访问权限必须大于等于父类的函数的访问权限
否则编译报错
4. 子类重写父类的函数的时候,返回值类型必须是父类函数的返回值类型或该返回值类型的子类。
不能返回比父类更大的数据类型: 如父类函数返回值的父类类型Object
子类对象查找属性或方法时的顺序:
原则:就近原则。
如果子类的对象调用方法,默认先使用this进行查找,如果当前对象没有找到属性或方法,找当前对象中
维护的super关键字指向的对象,如果还没有找到编译报错,找到直接调用。
重载和重写的不同
重载(overload):
1:前提: 所有的重载函数必须在同一个类中
2:特点: 函数名相同,参数列表不同,与其他的无关(访问控制符、返回值类型)
3:不同:参数个数不同 、 参数顺序不同、 参数类型不同
重写(override):
1:前提:继承
2:特点:函数名必须相同、参数列表必须相同。
思考:
1:为什么子类一定要访问父类的构造函数呢
子类继承了父类的属性,如果要使用父类的属性必须初始化,创建子类对象,必须先初始化父类属性
必须调用父类的构造方法。
2:为什么默认只调用父类无参的构造函数
设计java语言之时,只知道编译器会默认添加无参的构造函数,有参的无法确定。
但是可以通过super关键字显式调用父类指定构造函数。
3:为什么super()this()语句要放在构造函数的第一行
子类可能会用到父类的属性,所以必须先初始化父类。