继承
学习目标
1、理解什么是继承,学习继承有什么优缺点;
2、理解Java中继承有什么特点,什么时候使用继承;
3、能够正确定义继承关系并使用类的成员。
一、基本概念
Java中的继承,使用extends关键字,让类与类之间产生父子关系,被继承的类叫做父类(基类,超类),继承的类叫做子类(派生类)。Java的继承都是单继承的。
格式(extends)
class 父类 {
//...
}
class 子类 extends 父类 {
//...
}
子类继承父类后子类拥有父类的非私有成员。
二、继承的使用场景
多个类中存在相同的属性和行为时,可以将这些内容提出出来放到一个新类中,让这些类和新类产生父子关系,实现代码复用。
三、继承的优缺点
优点
1、功能复用:直接将已有的属性和行为继承过来,实现了功能的复用,节省了大量的工作;
2、便于扩展新功能:在已有功能的基础上,更容易建立,扩充新功能;
3、结构清晰,简化认识:同属于一个继承体系的相关类,它们之间结构层次清晰,简化了人们对代码结构的认识;
4、易维护性:不同类之间的继承关系,让这些事物之间保持一定程度的一致性,大大降低了维护成本。
缺点
1、打破了封装性:父类向子类暴露了实现细节,打破了父类对象的封装性;
2、高耦合性:类与类之间紧密的结合在一起,相互依赖性高。
程序设计追求
高内聚,低耦合;耦合即两个(或多个)模块相互依赖于对方,内聚即模块内部结构紧密,独立性强。
四、继承关系中类成员的使用
1、子父类间成员变量的使用
Java中使用变量的规则:遵循“就近原则”,局部位置有就使用没有就到成员位置找,有就使用没有就到父类中找,有就使用没有就报错。
使用 this 则直接指向成员,使用 super 则指向父类。
super关键字
本质:父类内存空间的标识;
使用super关键字引用父类成员:super.成员变量名/super.成员方法名;
调用父类的构造方法:super(参数列表);
super和this都写在方法的第一行,所以不能共用。
2、子父类间成员方法的使用
原则: 就近原则,本类—>父类—>更高父类…Object
访问父类方法方式:super.父类方法名();
定义重名方法的前提:父类功能不能完全满足功能需求,拓展父类功能;父类功能已过时,重新实现父类功能。
package demo;
//父类
public class Animal {
//吃东西
public void eat() {
System.out.println("吃东西");
}
//运动
public void sport() {
System.out.println("运动");
}
}
package demo;
//子类
public class Dog extends Animal {
//吃东西
@Override
public void eat() {
//调用父类的成员方法
super.eat();
System.out.println("吃骨头");
}
//运动
@Override
public void sport() {
System.out.println("跑来跑去");
}
}
package demo;
//测试类
public class Test {
public static void main(String[] args) {
//创建狗类对象
Dog dog = new Dog();
dog.eat();
dog.sport();
}
}
输出结果
3、子父类构造方法的使用
创建子类对象时优先调用父类构造方法;因为子类所有构造方法的第一行都有隐藏语句 super() 访问父类的空参构造。
五、方法重写
方法重写(用@Override 表示)
目的:使编写的代码更加灵活
定义:子类中出现和父类方法定义相同的现象
解释:方法重写也叫方法的重写、覆盖(子类的方法来覆盖父类的方法)
方法名、参数列表和返回值类型都相同
使用场景:扩展父类功能
注意事项:
父类的私有方法无法重写;
子类方法的访问权限不能小于父类方法;
子类不能比父类方法抛出更大的异常;
方法重载和方法重写的区别
六、Java中继承的特点
1、单继承;Java只支持类的单继承,但支持多层(重)继承;接口支持多继承
2、私有成员不能被继承,只能继承父类的非私有成员(成员变量,成员方法)
3、构造方法不能被继承,构造方法用于初始化本类的对象,创建子类对象时需要调用父类构造方法初始化该对象的父类内容,若父类构造方法可以被继承该操作会造成调用混乱
4、继承体现了“is a”的关系,子类符合“is a(是一个)”父类的情况才使用继承,其他情况不建议(组合has a,实现like a)