【Java】继承的特点和继承体系的设计
文章目录
一、继承的特点
继承的特点用一句话就能说明白:Java只支持单继承,不支持多继承,但支持多层继承。
我们可以把这句话分成三部分,挨个去解释一下。
1)Java只支持单继承
Java在当时为什么要这么去设计呢?
当时 James ,也就是右边的这哥们。当时它在设计 Java 的时候,是为了改进 C++ 语言中各种不合理的设计。在 C++ 中是允许多继承的,因此在 C++ 里面一个儿子可以有多个爸爸。但是 James 发现了,如果Java也沿袭这一设计的话,用起来相当不爽,有一种浑身蛋疼的感觉。
怎么个蛋疼法,我们来看一个场景。
假设 Java 也沿袭了 C++ 的多继承,第一个父类里面有一个方法 ,方法中打印一句话:让儿子去复习数学。
第二个父类中也有 方法,方法中打印一句话:让儿子去复习语文
子类同时继承了这两个父类,此时我们就可以来创建子类的对象,并调用方法。
在之前我们曾经说,子类可以直接使用父类中的方法。但是现在就会有个问题了,现在我调用的 是调用父类A里的,还是调用父类B中的呢?此时子类就不知道了。
因此为了避免这么尴尬的问题出现,James 在设计Java的时候,就取消了这一设计。
因此在Java中只能单继承,不能多继承。
但是它是可以多层继承的。
2)Java支持多层继承
多层继承:子类A继承父类B,父类B 可以 继承父类C。
这样跟我们现实中的祖宗三代是一样的了。
在它们的这个关系中,如果你单独来看左边的这两个类,儿子是子,爸爸是父。单看右边的这两个类,爸爸是子,爷爷是父。
那最左边的小孩,跟右边的爷爷,他们两个直接是什么关系呢?
在Java中,我们模糊了爷爷、太爷爷这样的关系,统称为父类。只不过我们会称爷爷是孙子的间接父类,而爸爸则是它的直接父类。
那子类又有父类,父类又有父类,那有没有一个尽头呢?
其实在Java中有一个最大的祖类,它叫做 。这个 是Java提前写好的,每一个类都直接或者间接的继承 。
在代码中,假如我书写了
public class A extends B { }
此时A是子类,B是父类,这个很明显。但是如果我没有写这样的继承关系,那么A就没有爸爸了吗?不是这样的。
public class B { }
A会默认的继承 类,这个关系不是我们自己写的,而是虚拟机在运行的时候自动帮你加上去的。
虚拟机在运行的时候会查看你当前这个类有没有父类,如果有,那没事了。如果说没有,虚拟机会给它加一个默认的继承关系,即继承 类。
3)继承体系
当我们这样的类写的越来越多的时候,会出现一个叫做:继承体系。
在继承体系最上面的类都是默认的继承于 ,下面所有的类都是间接继承于 类。
在一个继承体系当中,针对于任意一个子类,它可以使用自己直接父类里面的内容。
也可以使用自己间接父类里面的内容。
但是要注意,它不能使用这种类似于叔叔类中的内容。
4)总结
1、Java只能单继承:一个类只能继承一个直接父类
2、Java不支持多继承、但是支持多层继承。
3、Java中所有的类都直接或间接继承于 类。
二、练习:继承的练习(自己设计一个继承体系)
1)分析
自己在设计继承体系的时候有个诀窍:千万千万不要在自己的脑子里去脑补,光靠脑子去想肯定是不行的。
因为当一个体系比较复杂的时候,就会完全想不明白。
分享一个思想:画图法。顾名思义,先不要盲着去写代码,先把图画出来,然后再去利用那个图再去写代码,这样非常的方便。
画图的小诀窍:从下往上画,下面的东西是子类,上面的东西是父类。
我们在画的时候需要把子类中的共性内容抽取到父类中。
书写代码也有个小诀窍:从上往下写,因为需要先写爸爸,再写儿子。
2)代码
.java
package com.itheima.a01oopextendsdemo1;
public class Animal {
public void eat(){
System.out.println("吃东西");
}
public void drink(){
System.out.println("喝水");
}
}
.java(布偶猫)
package com.itheima.a01oopextendsdemo1;
public class Ragdoll extends Cat{
}
Cat.java
package com.itheima.a01oopextendsdemo1;
public class Cat extends Animal {
public void catchMouse() {
System.out.println("猫在抓老鼠");
}
}
Dog.java
package com.itheima.a01oopextendsdemo1;
public class Dog extends Animal{
public void lookHome(){
System.out.println("狗看家");
}
}
LiHua.java
由于中国狸花猫是我们清朝大国的品种,所以说它的名字就叫做:LiHua。
因为在之前我们说了,阿里巴巴编码规范,在阿里巴巴编码规范中有一条:如果拼音等同于英文,那么这个拼音是可以用的,例如这里的Lihua(狸花)。
package com.itheima.a01oopextendsdemo1;
public class LiHua extends Cat{
}
Husky.java
package com.itheima.a01oopextendsdemo1;
public class Husky extends Dog{
public void breakHome(){
System.out.println("哈士奇在拆家");
}
}
Teddy.java
package com.itheima.a01oopextendsdemo1;
public class Teddy extends Dog{
public void touch(){
System.out.println("泰迪又在蹭我的腿了~");
}
}
到目前为止,7个类就已经全部写完。这个代码其实还没有真正结束,因为我们还需要创建对象。现在我们写的这些类都属于 。接下来我们还需要再写一个测试类。在测试类里面写一个 main方法。
package com.itheima.a01oopextendsdemo1;
public class Test {
public static void main(String[] args) {
//创建对象并调用方法
//1.创建布偶猫的对象
Ragdoll rd = new Ragdoll();
rd.eat();
rd.drink();
rd.catchMouse();
System.out.println("----------------------");
//2.创建哈士奇的对象
Husky h = new Husky();
h.eat();
h.drink();
h.lookHome();
h.breakHome();
}
}
3)注意细节 1、测试
要注意,在下面代码中,使用 rd 去调用方法的时候,虽然我们在布偶类中一个方法也没写,但是它能调用的方法有很多很多。
那剩下的 等方法是哪来的呢?在Java中,它有个最大的祖宗类。如果一个类是没有父类的,这个类就会默认继承于 。
因此 类其实还继承于 类, 中有很多很多方法,这些方法有哪些作用,现在我们不用着急,后面会有个单独的章节去说这个 。
2、权限修饰符
如果说写方法的时候前面的权限修饰符,没有写 ,而是 ,这个时候子类就无法访问了。
这是因为 表示的是私有的意思,私有的东西只能在本类中访问,即 类,在其他类中就访问不到了。例如:爸爸的私房钱,是不是只有爸爸自己能用。
注意事项:子类只能访问父类中非私有的成员
package com.itheima.a01oopextendsdemo1;
public class Animal {
// 代码会报错
private void eat(){
System.out.println("吃东西");
}
public void drink(){
System.out.println("喝水");
}
}
三、总结
1、Java只能单继承,不能多继承,但是可以多层继承
2、Java中所有的类都直接或者间接继承于类
3、子类只能访问父类中非私有的成员
4、独立完成继承体系的案例