Java 中的多重继承

Java 中的多重继承

原文: https://howtodoinjava.com/oops/multiple-inheritance-in-java/

正如我们早已了解到的那样,Java 中不直接支持多重继承,而直到 Java 7 才支持。 Java 8 可以通过不带有菱形问题默认方法实现多继承的概念。

让我们看看如何?

Table of Contents

1\. What are default methods?
2\. How multiple inheritance is achieved via default methods?
3\. Possible conflicts and their resolutions

1. 什么是默认方法?

如果您有足够长的时间从事 Java 编程,您可能会意识到在现有接口中添加新方法可能会很痛苦。 您将需要在实现该接口的 java 类中实现该新方法。 这真的很难。 好吧,Java 8 带来了默认方法,可以在完全相同的情况下为您提供帮助。

默认方法使您可以向接口添加新功能,并确保向后兼容实现该接口的现有类。

顾名思义,接口中的默认方法是默认情况下将调用的方法 - 如果在实现类时未覆盖。 让我们看一个例子。

Moveable接口是一些现有接口,并且想要添加新方法moveFast()。 如果它使用旧技术添加了moveFast()方法,则实现Moveable的所有类也将被更改。 因此,我们将moveFast()方法添加为默认方法。

public interface Moveable 
{
    default void moveFast()
    {
        System.out.println("I am moving fast, buddy !!");
    }
}

如果所有实现Moveable接口的类都不需要自己更改(直到某些类专门想要覆盖moveFast()方法以添加自定义逻辑)。 所有类都可以直接调用instance.moveFast()方法。

public class Animal implements Moveable
{
    public static void main(String[] args)
    {
        Animal tiger = new Animal();

        //Call default method using instance reference
        tiger.moveFast();
    }
}

2. 如何通过默认方法实现多重继承?

多重继承是某些面向对象的计算机编程语言的特性,其中对象或类可以从多个父对象或父类继承特征和行为。

我们知道在 Java 中(直到 jdk 7),extends关键字支持 Java 中的继承,该关键字用于从父类创建子类。 您不能从两个类扩展。

在 Java 7 之前,接口仅用于声明必须实现哪些实现类的协定(除了abstract本身之外的实现类)。 因此,类可以继承的接口没有附加特定的行为。 因此,即使在一个类能够实现所需数量的接口之后,将其称为多重继承也是不合适的。

但是由于 Java 8 是默认方法,所以接口也具有行为。 因此,现在如果一个类实现了两个接口并且都定义了默认方法,那么它实质上是从两个父级继承行为,即多重继承

例如,在下面的代码Animal中,类未定义其自身的行为; 而是从父接口继承行为。 那是多重继承。

package com.howtodoinjava.examples;

interface Moveable
{
    default void moveFast(){
        System.out.println("I am moving fast, buddy !!");
    }
}

interface Crawlable
{
    default void crawl(){
        System.out.println("I am crawling !!");
    }
}

public class Animal implements Moveable, Crawlable 
{
    public static void main(String[] args) 
    {
        Animal self = new Animal();

        self.moveFast();
        self.crawl();
    }
}

3. 多重继承期间可能发生的冲突

在上面的示例中,我们有两个不同的接口和两个不同的方法 – 因此没有冲突。 如果两个接口都决定定义一个具有相同名称的新方法,该怎么办? 好了,他们可以毫无问题地进行定义。 但是,当Animal实例调用其名称时,将调用哪种方法。

那是矛盾的情况。

package com.howtodoinjava.examples;

interface Moveable
{
    default void run(){
        System.out.println("I am running, kid !!");
    }
}

interface Crawlable
{
    default void run(){
        System.out.println("I am running, daddy !!");
    }
}

public class Animal implements Moveable, Crawlable 
{
    public static void main(String[] args) 
    {
        Animal self = new Animal();

        //What will happen when below statement will execute
        //self.run();
    }
}

因此,要解决上述冲突,调用者类必须确定要调用的run()方法,然后使用如下所示的接口引用来调用。

Moveable.super.run();   //Call Moveable's run() method

//or 

Crawlable.super.run();  //Call Crawlable's run() method

这就是使用默认方法获得的 Java 8 多重继承特性的全部知识。

学习愉快!