继承
前言:
继承是多个类中存在相同属性和方法时,将这些内容放到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
多个类可以称为子类,单独这个类称为父类。(这样就不用多次写重复的代码了)
子类可以继承父类除构造方法(构造方法是类特有的,可以调用)外所有的属性和方法(包括Private私有属性和方法,)
可以直接访问父类中的非私有的属性和方法,不可以直接访问到父类的Private属性和方法。
通过 extends 关键字继承。
1. 理解继承的作用
继承是Java中实现代码重用的重要手段。
继承是面向对象的三大特性之一。
- 继承关系是传递的。若类C继承类B,类B继承类A,则类C既有从类B那里继承下来的属性与方法,也有从类A那里继承下来的属性与方法,还可以有自己新定义的属性和方法。继承来的属性和方法尽管是隐式的,但仍是类C的属性和方法。继承是在一些比较一般的类的基础上构造、建立和扩充新类的最有效的手段。
- 继承简化了人们对事物的认识和描述,能清晰体现相关类间的层次结构关系。
- 继承提供了软件复用功能。若类B继承类A,那么建立类B时只需要再描述与基类(类A)不同的少量特征(数据成员和成员方法)即可。这种做法能减小代码和数据的冗余度,大大增加程序的重用性。
- 继承通过增强一致性来减少模块间的接口和界面,大大增加了程序的易维护性。
- 提供多重继承机制。从理论上说,一个类可以是多个一般类的特殊类,它可以从多个一般类中继承属性与方法,这便是多重继承。Java出于安全性和可靠性的考虑,仅支持单重继承,而通过使用接口机制来实现多重继承。
2. 掌握继承的基本使用
-
将多个类(子类)抽取公共代码(属性、方法)到父类中。
(子类 is a 父类)public class Pet{ // 公共代码 }
-
使用子类去继承父类,即可拥有父类中的公共代码。
public class Dog extends Pet{ // 自己特有的 // 继承了父类中公共的 }
继承的注意事项:
- 子类不是无限继承父类中的内容,它只能继承父类中非私有(非private修饰)的代码,也不能继承构造方法,也不能继承不同包中,默认修饰的内容。
- 只能继承父类中非私有(非private修饰)的代码:private修饰的内容是私有的,只能在本类中使用。
- 不能继承构造方法:构造方法是用来初始化对象(对象创建),它是给父类创建对象用的。
- 不能继承不同包中,默认修饰的内容。
- 子类和父类之间要有is a的关系。
3. 掌握super关键字的使用
-
super:理解为:父类的
-
super可以用来调用属性、方法、构造器
-
super调用属性、方法
3.1 继承了以后,我们可以在子类的方法或构造器中,通过"super.属性"或者"super.方法"的方式,显式的调用父类中声明的属性或方法。但是很多情况下,我们都可以省略"super."
3.2 如果子类和父类中出现了同名的属性,那么我们如果在子类中调用父类中同名的属性的话,必须使用"super."的方式。
说明:子类的属性不会覆盖父类中同名属性。在堆空间中,两个属性都会存在。
3.3 如果子类重写了父类中的方法,那么我们我们希望在子类中调用父类中被重写的方法,必须使用"super."的方式。 -
super调用构造器:super(形参列表)
4.1 在子类的构造器的首行,显示的使用“super(形参列表)”的方式,调用父类指定的构造器。
4.2 针对于子类的某一个构造器而言,只能最多声明一个“super(形参列表)”。
4.3 在子类的构造器的首行,要么使用“this(形参列表)” ,要么使用"super(形参列表)",不能同时出现。
4.4 在子类构造器的首行,既没显式的使用“this(形参列表)”,也没显式的使用"super(形参列表)",那么默认提供的是:“super()”。
4.5 在子类的多个构造器中,至少一个构造器的首行使用了"super(形参列表)"。
4. 继承之后 加载顺序
加载顺序有两种:
1.单独类的加载顺序
静态变量、静态代码块(从上到下的顺序加载)
类的非静态变量,非静态块(从上到下的顺序加载)
构造函数
2.子类继承父类的加载顺序
父类静态变量、父类静态代码块(从上到下的顺序加载)
子类静态变量、子类静态代码块(从上到下的顺序加载)
父类的非静态变量、父类的非静态代码块(从上到下的顺序加载)
父类的构造方法
子类的非静态变量、子类的非静态代码块(从上到下的顺序加载)
子类的构造方法
说明:
静态方法、非静态方法只有在调用的时候才会执行,不调用不会执行,静态方法是类的方法,非静态方法需要对象调用。
变量赋值问题,Java中局部变量需要显式赋值后才能使用,成员变量也可直接显式赋值,但是如果没有给初始值,当加载声明的变量时这个时候是默认值。
继承加载顺序的小总结:
父类静态代码块 -> 子类的静态代码块 -> 【 父类的构造代码块 -> 父类的构造方法 -> 子类的构造代码块 -> 子类的构造方法 】