继承基本介绍和示意图
继承可以解决代码复用,让我们的编程更加靠近人类的思维。当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法只需要通过extends来声明继承父类即可。
继承的基本语法
class 子类 extends 父类 {
}
//1)子类就会自动拥有父类定义的属性和方法;
//2)父类又叫超类、基类;
//3)子类又叫派生类;
继承的深入讨论/细节问题
1.子类继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问,但是私有属性不能在子类直接访问,要通过父类提供公共的方法去访问;
2.子类必须调用父类的构造器,完成父类的初始化;( 隐藏super(); )
3.当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器;如果父类没有提供无参构造器,则必须在子类的构造器中用super去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过。
4.如果希望指定去调用父类的某个构造器,则显式的调用一下;super(参数列表)
5.super在使用时,必须放在构造器的第一行(只能在构造器中使用);
6.super() 和 this() 都只能放在构造器的第一行,因此这两个方法不能共存在一个构造器中;
7.Java所有类都是Object类的子类,Object是所有类的基类;
8.父类构造器的调用不限于直接父类!将一直往上追溯直到Object类(顶级父类);
9.子类最多只能继承一个父类(指直接继承),即Java中是单继承机制。
10.不能滥用继承,子类和父类之间必须满足is-a的逻辑关系;
Person is a Music?
Music extends Person
Animals
Cat extends Animal
继承的本质分析
当子类对象创建好后,建立了查找的关系
class GrandPa{
String name = "大头爷爷";
String hobby = "旅游";
}
class Father extends GrandPa {
String name = "大头爸爸";
int age = 39;
}
class Son extends Father {
String name = "大头儿子";
}
//===================
/*
Son son = new Son(); 内存的布局
son.name = ?
son.age = ?
son.hobby = ?
====================
?->这时请大家注意,要按照查找关系来返回信息
(1)首先看子类是否有该属性
(2)如果子类有这个属性,并且可以访问,则返回信息
(3)如果子类没有这个属性,就看父类有没有这个属性(如果父类有该属性,并且可以访问,就返回信息)
(4)如果父类没有就按照(3)的规则,继续找上级父类,直到Object...
加载类信息的过程:1->2->3->4
super关键字
基本介绍:super代表父类的引用,用于访问父类的属性、方法、构造器
基本语法
1.访问父类的属性,但不能访问父类的private属性:super.属性名;
2.访问父类的方法,但不能访问父类的private方法:super.方法名(参数列表);
3.访问父类的构造器(这点前面通过):super(参数列表);只能放在构造器的第一句,只能出现一局!
super给编程带来的便利/细节
1.调用父类的构造器的好处(分工明确,父类属性由父类初始化,子类的属性由子类初始化)
2.当子类中有和父类中的成员(属性和方法)重名时,为了访问父类的成员,必须通过super。如果没有重名,使用super、this、直接访问是一样的效果!
3.super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用super去访问爷爷类的成员;如果多个基类(上级类)中都有同名的成员,使用super访问遵循就近原则;A->B->C
super和this的比较
方法重写/覆盖(override)
基本介绍:简单地说方法覆盖(重写)就是子类有一个方法,和父类的某个方法的名称、返回类型、参数一样,那么我们就说子类的这个方法覆盖了父类的方法
注意事项和使用细节
方法重写也叫方法覆盖,需要满足下面的条件
1.子类方法的参数,方法名称,要和父类方法的参数、方法名称完全一样
2.子类方法的返回类型和父类方法的返回类型一样,或者是父类返回类型的子类
//比如 父类 返回类型是Object,子类方法返回类型是String
public Object getInfo(){}
public String getInfo(){}
3.子类方法不能缩小父类方法的访问权限
void sayOk(){}
public void sayOk(){}
// public > protected > 默认 > private