Java 的每个新版本都与之前的版本不同。下面是我们介绍过的材料变化的示例:在 Java 5 之前,该语言没有
同样,Java 8 与 Java 7 也有明显不同。我们的大部分课程都是为该语言的第 7 版编写的,但我们当然不会忽略重要的创新。由于我们已经在本课中讨论了接口,因此我们将考虑一个更新——接口中的默认方法。您已经知道接口不实现行为。它的任务是描述所有实现它的对象必须具有的行为. 但是开发人员经常会遇到一个方法的实现在所有类中都相同的情况。让我们考虑一下我们的旧车示例:
enum
s。 
public interface Car {
public void gas();
public void brake();
}
public class Sedan implements Car {
@Override
public void gas() {
System.out.println("Gas!");
}
@Override
public void brake() {
System.out.println("Brake!");
}
}
public class Truck implements Car {
@Override
public void gas() {
System.out.println("Gas!");
}
@Override
public void brake() {
System.out.println("Brake!");
}
}
public class F1Car implements Car {
@Override
public void gas() {
System.out.println("Gas!");
}
@Override
public void brake() {
System.out.println("Brake!");
}
}
“在你看来,这段代码的主要问题是什么?你可能注意到我们写了一堆重复的代码!这个问题在编程中很常见,你需要避免它。之前没有特定的解决方案是另一回事Java 8 发布了。随着这个版本的到来,可以指定默认方法并在接口内部实现它们!这是你如何做到的:
public interface Car {
public default void gas() {
System.out.println("Gas!");
}
public default void brake() {
System.out.println("Brake!");
}
}
public class Sedan implements Car {
}
public class Truck implements Car {
}
public class F1Car implements Car {
}
现在,所有汽车都相同的gas()
和方法已移至界面。brake()
不需要重复的代码。更重要的是,这些方法在每个类中都可用!
public class Main {
public static void main(String[] args) {
F1Car f1Car = new F1Car();
Sedan sedan = new Sedan();
Truck truck = new Truck();
truck.gas();
sedan.gas();
f1Car.brake();
}
}
如果有 100 个类使用该gas()
方法,但其中只有 99 个具有相同的行为怎么办?这是否会破坏一切并使默认方法不适合这种情况?当然不是:) 接口中的默认方法可以像普通方法一样被覆盖。
public class UnusualCar implements Car {
@Override
public void gas() {
System.out.println("This car accelerates differently!");
}
@Override
public void brake() {
System.out.println("This car decelerates differently!");
}
}
所有 99 种其他类型的汽车将执行默认方法,并且UnusualCar
作为例外的类不会破坏全局并冷静地定义自己的行为。接口的多重继承。如您所知,Java 不支持多重继承。这件事情是由很多原因导致的。我们将在单独的课程中详细介绍它们。其他语言(例如 C++)确实支持它。如果没有多重继承,就会出现一个严重的问题:一个对象可以有几种不同的特征和“行为”。这是生活中的一个例子:我们是父母的孩子,我们是老师的学生,我们是医生的病人。在生活中,我们扮演不同的角色,相应地,行为也不同:显然,我们不会像与亲密朋友交谈那样与老师交谈。让我们尝试将其转化为代码。假设我们有两个类:池塘和鸟舍。对于池塘,我们需要水禽;对于鸟舍,我们需要会飞的鸟。为此,我们创建了两个基类:FlyingBird
和Waterfowl
。
public class Waterfowl {
}
public class FlyingBird {
}
相应地,我们会将继承类的鸟送到FlyingBird
鸟舍,将继承类的鸟送到Waterfowl
池塘。一切看起来都很简单。但是我们要把鸭子送到哪里呢?它会游泳和飞翔。而且我们没有多重继承。幸运的是,Java 支持接口的多种实现。虽然一个类不能继承多个父类,但它可以轻松实现多个接口! 我们的鸭子既可以是飞鸟也可以是水禽:)我们只需要创建FlyingBird
接口Waterfowl
而不是类来实现预期的结果。
public class Duck implements FlyingBird, Waterfowl {
// The methods of both interfaces can be easily combined into one class
@Override
public void fly() {
System.out.println("Fly!");
}
@Override
public void swim() {
System.out.println("Swim!");
}
}
因此,我们的程序保留了类的灵活性,结合默认方法,我们定义对象行为的能力几乎是无限的!:)
GO TO FULL VERSION