# Java 中的多重继承

> 原文： [https://howtodoinjava.com/oops/multiple-inheritance-in-java/](https://howtodoinjava.com/oops/multiple-inheritance-in-java/)

正如我们早已了解到的那样，Java 中不直接支持**多重继承**，而直到 Java 7 才支持。 [Java 8](https://howtodoinjava.com/java-8-tutorial/) 可以通过不带有[**菱形问题**](https://howtodoinjava.com/oops/java-inheritance/)的[默认方法](https://howtodoinjava.com/java8/default-methods-in-java-8/)实现**多继承**的概念。

让我们看看如何？

```java
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()`方法添加为默认方法。

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

```

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

```java
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`](https://howtodoinjava.com/oops/extends-vs-implements/)关键字支持 Java 中的继承，该关键字用于从父类创建子类。 您不能从两个类扩展。

在 Java 7 之前，接口仅用于声明必须实现哪些实现类的协定（除了[`abstract`](https://howtodoinjava.com/java/basics/abstract-keyword/)本身之外的实现类）。 因此，类可以继承的接口没有附加特定的行为。 因此，即使在一个类能够实现所需数量的接口之后，将其称为多重继承也是不合适的。

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

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

```java
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`实例调用其名称时，将调用哪种方法。

那是矛盾的情况。

```java
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()`方法，然后使用如下所示的接口引用来调用。

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

//or 

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

```

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

学习愉快！