likes
comments
collection
share

Java是单继承的?

作者站长头像
站长
· 阅读数 23

Java是单继承的?

Java的什么是单继承的?

类?

接口?

不骗你,我之前确实知道Java是单继承的,但是我以为类和接口都是单继承的!

直到一个偶然间我在翻看RedisTemplate相关源码的时候,看到了这个:

public interface RedisCommands extends RedisKeyCommands, RedisStringCommands, RedisListCommands, RedisSetCommands, RedisZSetCommands, RedisHashCommands, RedisTxCommands, RedisPubSubCommands, RedisConnectionCommands, RedisServerCommands, RedisStreamCommands, RedisScriptingCommands, RedisGeoCommands, RedisHyperLogLogCommands {
    @Nullable
    Object execute(String var1, byte[]... var2);
}

当时简直打碎了我的三观。

这代码写的不对吧,Java不是单继承的么?可他怎么能继承这么多接口。

后来,经过翻阅大量资料(说到底就是问度娘呗),终于确认了:Java是单继承的不假,但指的是类是单继承的,而接口是多继承、多实现的。

为什么Java类是单继承的?

为什么Java类要设计成单继承的呢?我给他多继承行不行?

为了验证类的多继承的可行性,我们来写个demo来验证下。

class Father{

    void sleep(){
        System.out.println("凌晨一点睡觉。。。");
    }
}

class Mother{
    
    void sleep(){
        System.out.println("晚上十一点准时睡觉。。。");
    }
}

// 伪代码
class Son extends Father,Mother{

}
  • 假设Father和Mother都有一个sleep方法。

  • 然后Son要继承Father和Mother。

  • 那么Son到底是要继承Father的sleep方法呢,还是继承Mother的sleep方法呢?

  • 继承哪个父类的sleep方法都不合理!这也就是Java类只能单继承的原因。

为什么Java接口可以多继承?

Java接口多继承就没有问题?

我们继续写个demo看看有没有问题:

interface IFather{
    void sleep();
}

interface IMother{
    void sleep();
}

interface ISon extends IFather,IMother{
    
}
  • 假设IFather和IMother都有一个sleep方法。

  • 然后ISon要继承IFather和IMother。

  • 那么Son到底是要继承Father的sleep方法呢,还是继承Mother的sleep方法呢?

  • 不重要,不管是哪个sleep方法,都需要通过Son的实现类去实现sleep这个方法。

  • 所以接口的多继承就是没问题的。

接口的默认方法怎么多继承?

接口的多继承真的没有问题吗?那JDK8之后加入的默认方法也可以多继承吗?

我们继续用代码看下:

interface IFather{

    default void getUp(){
        System.out.println("九点起床上班。。。");
    }

    void sleep();
}

interface IMother{

    default void getUp(){
        System.out.println("睡到十二点才想起起床。。。");
    }
    
    void sleep();
}
  • 这时候IFather和IMother都新增了一个默认方法getUp

  • 那么ISon该怎样同时继承他们呢?

interface ISon extends IFather,IMother{

    @Override
    default void getUp() {
        System.out.println("八点起床上学");
    }
}
  • 是的,你没有看错,直接重写getUp默认方法就好啦

嗯……好像是这样,那Java接口的多继承没问题了。

为什么Java的多继承问题不能通过重写方法来解决呢?

但是,既然Java接口的默认方法可以通过重写来解决多继承问题,那么为什么Java的多继承问题不能通过重写方法来解决呢?

继续上面的例子,如果重写方法的话应该是这样:

// 伪代码
class Son extends Father,Mother{
    void sleep(){
        System.out.println("晚上九点准时睡觉。。。");
    }
}

这种方式肯定是不行的。

可能这时候有人会有疑问了。

Java类的多继承问题不能用重写方法来解决,为什么Java接口的默认方法却能用重写来解决呢?

我们首先得明白:

普通类和接口的区别(只论述和本文相关特点,不细聊)

Java在设计的时候,

类更侧重于描述对象的特征和功能,是具象的东西。

而接口则更偏向于定义一套规范,是个抽象的东西。

类在继承的时候,就是想拥有父类的特征和功能,这时候你如果进行重写,就会失去父类的特性和功能,也就失去了意义;

而接口在继承的时候,是想拥有父接口定义的规范,而默认方法更多的是描述本接口的特有功能,所以在继承的时候重写默认方法更加符合Java对于接口的定义。

总结

到此,我们了解到:

  • Java类是单继承的

  • Java接口是多继承的

  • 默认方法的多继承可以通过重写来解决

  • 重写并不能作为Java多继承问题的解决方案

文中如有不足之处,欢迎指正!一起交流,一起学习,一起成长 ^v^