首先说一下什么是继承:
继承的概念:
将多个类中的共同代码单独提取出来,形成一个独立的类, 多个类和当前独立的类产生一种关系: 继承关系 extends
继承的好处:
1)提高了代码的复用性
2)提高了代码维护性
3)类和类产生这种关系,是多态的前提条件!
Java中继承的特点:
1)在Java中,只支持单继承,不支持多继承,在别的语言可能有多继承存在多继承的语言:class 子类名 extends 父类名1,父类名2{}
2)在Java中,虽然不支持多继承,但是可以多层继承! (分层初始化:先让父类初始化再是子类初始化)
3)在Java中,所有的Java类(自己定义的,Jdk提供的)都继承自 Object类 (超类)
继承中的注意事项:
1)子类继承父类,只能继承父类非私有的成员(成员变量,成员方法),但是可以通过公共方法间接的访问!
2)子类不能继承父类的构造方法,但是可以通过关键字 间接访问父类的构造方法(等会讲super)
3)不要为了部分使用功能去使用"继承"
继承中成员的组成
成员变量
构造方法
成员方法
成员变量
1)子类继承父类,子类中的成员变量名称和父类中的成员变量不一致的情况:比较简单,分别输出!
2)子类继承父类,子类中的成员变量名称和父类中的成员名称一致的情况:(重点)
a)先在子类的局部位置中找,如果存在,就使用
b)如果在类的局部位置没有,那么在子类的成员位置找,如果存在,就使用
c)如果子类的成员位置没有,那么在父类的成员位置找,如果存在,就使用
d)如果父类的成员位置都没有,那么就报错!
继承中构造方法初始化的特点(分层初始化!)
继承中,子类不能继承父类的构造方法,但是可以通过super访问父类的构造方法
子类的构造方法中(无参/有参),都会默认访问父类的无参构造方法,
由于子类继承父类,子类可能会用到父类中数据,所以先让父类进行初始化,再让子类初始化!(分层初始化!)
关于super():访问无参构造方法,必须写在子类构造方法中第一句话
什么是多态:
一个事物在不同时刻的不同状态
举例:
Animal a = new Cat() ; //猫是动物
Cat c = new Cat() ; //猫是猫
多态内存图:
多态的前提条件:
1)必须有继承关系 (产生一个中extends 关系)
2)需要有方法重写子类继承父类的时候,需要使用子类的功能,需要将父类的功能覆盖掉! 举例:猫狗案例
Animal, eat()和sleep(),每个动物的吃和睡的行为不同!
3)必须有父类引用指向子类对象 (向上转型)
Fu f = new Zi() ; 在内存中使用子类实例化(创建对象),但是子类继承父类,通过构造方法 让父类初始化
多态的好处:
1)提高代码的维护性(继承来保证)
2)提高代码的扩展性(由多态保证)
多态的成员访问特点:
Fu f = new Zi() ;
1)成员变量(非静态变量) 编译看左,运行看左边 (看父类)
2)构造方法
Fu f = new Zi() ; 内存创建的是子类对象,但是存在继承关系,执行构造方法先让父类初始化完毕,然后在初始化子类
3)成员方法(非静态) (方法重写,说的非静态的方法!) 编译看左,运行看右 (因为存在方法重写,运行看的右边)
4)静态的成员方法: 编译看左,运行看左(静态方法算不上方法重写,跟类先关,优先父类进行数据初始化,function方法先进内存)
父类引用.静态方法名()--调用父类的方法
多态的弊端:
父类引用指向子类对象(向上转型),无法访问子类的特有功能!
需要访问子类特有功能,怎么办?
1)直接在测试的时候,子类去创建自己的对象 Son s = new Son()
可以访问,但是从内存角度考虑,重新在堆内存中开辟空间,耗费空间的内存!
2)如果能够类似于这种方式:父类引用指向子类对象,访问的是父类,如果能够将父类的引用转换为子类引用 是可以的,
将父类的引用强制转换为子类的引用 :向下转型
Zi zi = (Zi)f;
来源:51CTO
作者:qq5e01e21075ea4
链接:https://blog.51cto.com/14651315/2465094