章
目
录
在Java 1.7版本之前,Java不支持多重继承。自从Java 8版本开始,我们可以通过使用默认方法来实现多重继承的概念,而不会陷入菱形继承问题。
1.什么是多重继承?
在多重继承中,子类可以从多个父类中继承行为。需要注意的是,Java类可以实现多个接口,但接口本身并不定义具体的行为,而只用于定义契约。因此,实现多个接口并不会向类添加行为,因此它并不是多重继承。
在下面的图表中,类D继承了类A和类B。通过这种方式,D可以继承这两个类的非私有成员。但是,在Java中,我们不能使用”extends”关键字来继承两个类。因此,在Java中不可能实现这种形式的多重继承。
2. 什么是默认方法?
如果您已经从事 Java 编程足够长的时间,您可能会意识到向现有接口添加新方法是多么痛苦。我们必须在实现该接口的所有类中实现该新方法。这是一项非常困难的工作,并且经常破坏代码和设计。好吧,Java 8 带来了默认方法来帮助解决这个确切的问题。
默认方法使我们能够向接口添加新功能,并确保实现该接口的现有类的向后兼容性。
顾名思义,接口中的默认方法是默认情况下将调用的方法 – 如果在实现类中未重写的话。让我们通过一个例子来理解。
Moveable
接口是一个现有的接口,我们要添加一个新的方法moveFast()
。如果我们使用旧技术在Moveable
添加moveFast()方法,那么所有实现的类也将被更改。因此,让我们添加moveFast()
方法作为默认方法。
public interface Moveable {
default void moveFast() {
System.out.println("I am moving fast");
}
}
在这种情况下,所有实现Moveable接口的类都不需要更改自身(直到某些类特别想要重写moveFast()
方法以添加自定义逻辑。所有类都可以直接调用instance.moveFast()
方法。
class Animal implements Moveable { }
Animal tiger = new Animal();
//Call default method using instance reference
tiger.moveFast();
我们可以根据需要在接口中添加任意数量的默认方法。
3.默认方法如何实现多重继承?
从 Java 8 开始,接口不仅定义契约,还包含使用默认方法的行为。因此,如果一个类实现两个接口并且都定义了默认方法,那么该类本质上继承了两个父级的行为,这就是多重继承。
例如,在下面的代码中,Animal
类没有定义它自己的任何行为;相反,它从父接口继承行为。
interface Moveable {
default void moveFast() {
System.out.println("I am moving fast");
}
}
interface Crawlable {
default void crawl(){
System.out.println("I am crawling");
}
}
public class Animal implements Moveable, Crawlable { }
我们可以按如下方式验证行为:
Animal self = new Animal();
self.moveFast();
self.crawl();
4. 可能的冲突
在上面的例子中,我们有两个不同的接口和两种不同的方法——所以不存在冲突。如果两个接口都决定定义一个同名的新方法怎么办?好吧,他们可以毫无问题地定义。但是当Animal实例通过名称调用方法时,将调用哪个方法。
interface Moveable {
default void run() {
System.out.println("I am moving fast");
}
}
interface Crawlable {
default void run(){
System.out.println("I am crawling");
}
}
public class Animal implements Moveable, Crawlable { }
现在当我们调用animal.run()方法时会发生什么?
Animal animal = new Animal();
animal.run();
这是一个矛盾的情况。为了解决上述冲突,调用者类必须决定要调用哪个run()方法,然后使用接口的引用进行调用。
Moveable.super.run(); //调用 Crawlable的 run() 方法
//or
Crawlable.super.run(); //调用 Crawlable的 run() 方法
这就是您应该了解的有关 Java 8 中使用默认方法的多重继承功能的全部内容。
文章目录前言 第1章 Java语言基础 第2章 流程控制语句 第3章 面向对象编程 第4章 Java 字符串 […]