面向对象-继承
1. 继承的概念
继承可以理解为就是让两个类(事物)产生从属关系,有了从属关系子类就肯定会具有父类的特征(父类中的非私有成员),这样我们用类去描述一些事物的时候就可以更方便
1.1 相关名词
超类,父类都是同一个概念就是叫法不同
派生类,子类都是同一个概念就是叫法不同
2. 继承的格式
在子类名后面加extends 父类名
例如
public class Dog extends Animal {
//Dog就成为了Animal的一个子类
}
3. 继承的注意事项
- java中类只能单继承,一个类只能有一个父类,但是可以多层继承
- 要有实际的从属关系才可以继承,不能不合逻辑的任意继承。
4. 继承的优缺点
4.1 优点
提高了代码的复用性
4.2 缺点
增加了类和类之间的耦合性。违背了`高内聚,低耦合`原则
5. 继承后成员相关语法
5.1 成员变量
父类非私有的成员变量才会继承给子类。所以当我们看到使用子类对象的某个成员变量时,有可能这个成员变量是定义在子类中。也有可能是定义在其父类中。
父类中如果已经有了某个成员变量,我们不应该再在子类中定义同名的成员变量。否则可能会导致非常难排查的Bug。
5.2 构造方法
构造方法不会继承给子类
子类的构造中必须调用父类的构造并且要求在第一行。
子类的构造默认都会在第一行调用父类的无参构造,所以当父类没有无参构造的时候子类构造中会报错。解决方案是给父类加上无参构造或者在子类构造中显示的调用父类的有参构造。
理解
问:继承的时候构造方法为什么不会被继承?
答: 假设会被继承,这个方法名和子类的类名就肯定不相同,所以不能算是构造方法.所以假设不成立
问:子类的构造方法会默认调用父类的无参构造super().为什么?
答:因为父类中可能有成员变量,并且这个成员变量要继承给子类使用,但是所有的变量在使用之前必须先赋值.而父类的成员变量只能用父类的构造进行默认的初始化。
问:在子类的构造方法中,能不能把父类的构造放到第二行?
答:不能,因为要保证成员变量先初始化了.如果放到第二行,有可能在第一行还没初始化的时候就使用的父类的成员变量
5.3 成员方法
父类非私有的成员方法会继承给子类。所以当我们看到使用子类对象的某个成员成员方法时,有可能这个成员方法是定义在子类中。也有可能是定义在其父类中。
6. 方法重写
6.1 方法重写的概念
当子类拥有父类继承下来的某个功能(成员方法),但是在子类中对这个方法的具体实现和父类不同。这个时候我们在子类中定义了一个和父类方法相同的方法(包括返回值类型,方法名,参数列表) ,这就叫做方法重写。
6.2 注意事项
我们在重写方法的时候方法的权限修饰符其实可以和父类不同**(一般都相同)**。但是子类中方法的权限不能比父类低。**(权限修饰符 : private < 默认(什么都不写) < protected < public)**
我们在重写方法的时候方法的返回值类型其实可以不同**(一般都相同)**。但是要求子类中方法的返回值类型必须是父类方法返回值类型的子类。
我们可以用 [@Override ](/Override ) 注解来校验是不是方法重写。
私有的方法不能被重写,因为私有的不会被继承
6.3 小思考
面试题:说说overload和override的区别。
答:
方法重载:在同一个类中,方法名相同,参数列表不同,和返回值无关
方法重写:在子父类中,子类有一个和父类方法名相同,参数列表相同,返回值类型也相同的方法。这个就叫方法的重写
7. this和super
this就代表本类的,super就代表父类的
使用:
- 访问成员变量
- this.成员变量名 本类的成员变量
- super.成员变量名 父类的成员变量
- 访问成员方法
- this.成员方法名(参数) 调用本类的成员方法
- super.成员方法名(参数) 调用父类的成员方法
- 调用构造方法
- this(参数) 调用本类的构造方法
- super(参数) 调用父类的构造方法