每个新版本的 Java 都与以前的版本不同。enums作为我们所介绍材料的这种变化的一个例子,该语言在 Java 5 之前 没有。
接口中的默认方法 - 1
因此,Java 8 与 Java 7 明显不同。当然,我们不会忽视重要的创新。由于我们在本课中讨论接口,让我们考虑对该语言的一个更新:接口中的默认方法。您已经知道接口不实现行为。它的目的是描述实现该接口的所有对象中必须存在的行为。但是开发人员经常会遇到一个方法的实现在所有类中都相同的情况。让我们看看我们的旧车示例:

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 go() {
       System.out.println("Gas!");
   }

   @Override
   public void brake() {
       System.out.println("Brake!");
   }
}


public class F1Car implements Car {
   @Override
   public void go() {
       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 go() {
       System.out.println("This car accelerates differently!");
   }

   @Override
   public void brake() {
       System.out.println("This car slows down differently!");
   }
}
其余99款车型均采用默认方式,而UnusualCar班级是个例外。在不破坏大局的情况下,它会冷静地定义自己的行为。接口中的多重继承。如您所知,Java 中没有多重继承。这件事情是由很多原因导致的。我们将在单独的课程中详细讨论它们。在其他语言中,例如 C++,情况正好相反。没有多重继承是一个严峻的挑战,因为同一个对象可以有几个不同的特征和行为。例如,我们是父母的孩子,老师的学生,医生的病人。在现实生活中,我们扮演着不同的角色,因此行为也不同:显然,我们与老师的互动不同于与亲密朋友的互动。让我们尝试将这种情况转化为代码。假设我们有两个类:Pond 和 Aviary。池塘需要游泳的鸟,而鸟舍需要飞翔的鸟。为了表示这一点,我们创建了两个基类:FlyingBirdWaterfowl

public class Waterfowl {
}

public class FlyingBird {
}
因此,我们会将继承的鸟类送到FlyingBird鸟舍,而那些继承的鸟类Waterfowl将进入池塘。一切似乎都很简单。但是如果我们需要在某处定义一只鸭子,我们应该怎么做呢?鸭子既会游泳也会飞。但是我们没有多重继承。幸运的是,Java 支持接口的多种实现。如果一个类不能继承多个父类,实现多个接口很容易!我们的鸭子可以是飞翔的鸟,也可以是游泳的鸟 :) 为了达到预期的效果,我们需要做的只是创建FlyingBird接口Waterfowl而不是类。

public class Duck implements FlyingBird, Waterfowl {

   // Methods of both interfaces combine easily into one class
  
   @Override
   public void fly() {
       System.out.println("Flying!");
   }

   @Override
   public void swim() {

       System.out.println("Swimming!");
   }
}
这意味着我们的程序保留了灵活管理班级的能力。当我们将其与默认方法结合使用时,我们确定对象行为的能力几乎变得无限!:)