4.面向对象_继承
4.1继承的概述
- 提高了代码的复用性。
- 让类与类之间产生了关系,有了这个关系,才有多态的特性。
注意:千万不要为了获取其他类的功能而去继承,简化代码而继承。必须是类与类之间有所属关系才可以继承,所属关系 is a 。
Java语言中:Java只支持单继承,不支持多继承。因为多继承容易带来安全隐患。但多个父类定义了相同的功能时,当功能内容不同时,子类对象不确定实现哪一个。
但是Java保留这种机制,并用类一种体现形式来完成表现,多实现。Java支持多层继承。也就是一个继承体系。
如何使用一个体系中的功能呢?想要使用体系,先查阅体系父类的描述,因为父类中定义的是体系中最共性的功能,通过了解共性功能,就可以知道该体系的基本功能。那么这个体系已经基本可以使用了。
那么在具体调用时,要创建最子类的对象,为什么呢?一是因为有可能父类不能创建对象,二是因为创建子类对象可以获取更多功能,包括基本的也包括特有的。
简单一句话:查阅父类功能,创建子类对象,使用功能。
4.2继承的特点
子父类出现后:类成员的特点
- 变量
- 函数
- 构造函数
4.3super关键字
1、子父类中的变量:如果子父类中出现非私有的同名成员变量时,子类要访问本类的变量,用this;子类要访问父类中的同名变量时,用super。
super的使用和this的使用几乎一致。this代表的是本类对象的引用,super代表的是父类的引用。
4.4函数覆盖
2、子父类中的函数:当子类出现和父类一模一样的函数时,当子类对象调用该函数,会运行子类函数的内容。如同父类的函数被覆盖和一样。这种情况是函数的另一个特性:重写(覆盖)
当子类继承父类,沿袭了父类的功能到子类中,但是子类虽然具备该功能,但是功能内部的内容却不一致,这是没有必要定义新功能,而是使用覆盖特性,保留父类的功能定义,并重写功能的内容。
覆盖:1、子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败。2、静态只能覆盖静态。
注意:重载:只看同名函数的参数列表。重写:子父类方法要一模一样。包括返回值类型。
4.5子类的实例化过程
3、子父类中的构造函数:在对子类对象进行初始化时,父类的构造函数也会运行,那是因为子类的构造函数默认第一行有一条隐式的语句super();
super();会访问父类中空参数的构造函数,而且子类中所有的构造函数默认第一行都是super();
为什么子类一定要访问父类中的构造函数?因为父类中的数据子类可以直接获取,所以子类对象在建立时,需要先查看父类中对这些数据是如何进行初始化的。所以子类在对象初始化时,要先访问一下父类中的构造函数。如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。
注意:super 语句一定定义在子类构造函数的第一行。
结论:子类中所有的构造函数,默认都会访问父类中空参数的构造函数。因为子类每一个构造函数内都有一条隐式的语句super();,当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问父类中的构造函数。当然:子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。子类中最少有一个构造函数会访问父类中的构造函数,在子类构造函数中this语句和super语句只能存在一个
4.6final关键字
- final可以修饰类、方法、变量
- final修饰的类不可以被继承(限制全部),为了避免被继承,被子类复写功能。
- final修饰的方法不可以被覆盖(限制局部),既可以修饰成员变量也可以修饰局部变量。
- final修饰的变量是一个常量,只能被赋值一次。(当描述事物时,一些数据的出现值是固定的,那么这时为了增强阅读性,都给这些值起个名字,方便于阅读,而这个值不需要改变,所以加上final修饰。作为常量:常量的书写规范所有的字母都要大写,如果由多个单词组成,单词间通过下划线_连接。)
- 内部类只能访问被final修饰的局部变量
4.7 抽象类
当多个类中出现相同功能,但是功能主体不同,可以进行向上抽取。这时只抽取功能定义,而不抽取功能主体。抽象:看不懂。
抽象类的特点:
- 抽象方法一定在抽象类中;
- 抽象方法和抽象类都必须被abstract关键字修饰;
- 抽象类不可以用new创建对象,因为调用抽象方法没意义。
- 抽象类中的方法要被使用,必须由子类复写其所有的抽象方法后,建立子类对象调用。如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。
抽象类和一般类没有太大的不同。该如何描述事物,就如何描述事物。只不过该事物出现了一些看不懂的东西。这些不确定的部分,也是该事物的功能,也需明确出现。但是无法定义功能主体。通过抽象方法来体现。
抽象类比一般类多了抽象方法。抽象不可以实例化。特殊:抽象类可以不定义抽象方法(目的:不让该类建立对象)。
模板方法模式:在定义功能时,功能的一部分是确定的(不想被子类复写用final修饰),但是有一部分是不确定的(当事物有默认的实现时,不一定用abstract修饰)。而确定的部分在使用不确定的部分,那么这时就将不确定的部分暴露出去,由该类的子类去完成。
4.8 接口
4.8.1接口的表现形式与类的关系
- 格式:interface{}
- 接口中的成员修饰符是固定的。
- 成员变量:public static final
- 成员函数:public abstract
- 接口的出现将“多继承”通过另一种形式体现出来,即“多实现”。
接口:是不可以创建对象的,因为有抽象方法。需要被子类实现,子类对接口中的抽象方法全部覆盖后,子类才可以实例化。否则子类也是一个抽象类。接口可以被类多实现,也是对多继承不支持的转换形式。Java支持多实现。
一个类继承了另一个类的同时还能实现多个接口。接口与接口之间存在多继承,类与类之间只支持单继承,类与接口之间存在多实现。
4.8.2接口的特点
- 接口是对外暴露的规则
- 接口是程序的功能扩展
- 接口可以用来多实现
- 接口于类之间是实现关系,而且类可以继承一个类的同时还能实现多个接口
- 接口与接口之间可以有继承关系