代码之家  ›  专栏  ›  技术社区  ›  Patrick C.

Java8:关于功能接口

  •  6
  • Patrick C.  · 技术社区  · 7 年前

    我想询问以下与功能接口相关的代码。 我感到困惑的是:

    Rideable rider = Car :: new
    

    是否正在创建 Rideable (接口)或 Car (类)实例? 如果它正在创建 汽车 对象,构造函数 new Car() (即没有参数)应该不存在,那么这怎么可能有效?

    我一直在通读 this tutorial ,但仍然无法理解。

    @FunctionalInterface 
    interface Rideable {
      Car getCar (String name);
    }
    
    class Car {
      private String name;
    
      public Car (String name) {
        this.name = name;
      }
    }
    
    public class Test {
      public static void main(String[] args) {
        Rideable rider = Car :: new; 
        Car vehicle = rider.getCar("MyCar");
      }
    }
    
    3 回复  |  直到 6 年前
        1
  •  5
  •   Eran    7 年前

    它是在创建一个可驾驶(接口)还是汽车(类)实例?

    它正在创建(实现的类)的实例 Rideable 界面

    这个 可骑行的 功能接口具有单一方法- getCar -接受 String 参数,并返回 Car 例子

    这个 public Car (String name) 构造函数接受 一串 参数并生成 汽车 例子

    因此方法参考 Car::new (在本例中,它不引用无参数构造函数)可以用作 可骑行的 界面

    如果这有助于澄清混淆,这里有一个lambda表达式,相当于 汽车::新 方法参考:

    Rideable rider = (String s) -> new Car(s);
    

    Rideable rider = s -> new Car(s);
    
        2
  •  1
  •   Alex Mamo    7 年前

    您正在使用Lambda语法来实现 getCar() 方法,其中使用Lambda的简明语法省略了以下匿名类程序:

    Rideable rideable = new Rideable() {
        @Override
        public Car getCar(String name) {
            return new Car(name);
        }
    };
    

    这是Java 7代码。使用Lambda表达式可以实现同样的效果:

    Rideable rider = name -> new Car(name);
    

    或者,如您的示例所示,使用方法引用:

    Rideable rider = Car::new;
    

    因此 getCar(String) Ridable对象的方法可以用作 new Car(String) .

    作为对问题的回答,您正在创建 Car 实现可RIDABLE接口的类。这是实现接口的另一种方法,无需使用 implement 关键字。

    如果您正在考虑:

    Car auto = Car("MyCar")::new;
    

    Car auto = Car::new;
    Car vehicle = auto::getCar("MyCar");
    

    Car vehicle = Rideable::new::getCar("MyCar");
    

    所有这些示例都是 wrong 方法。我给您举了这个例子,因为这些是在讨论Lambda表达式或方法引用时可能犯的常见错误。

        3
  •  1
  •   Chota Bheem    7 年前

    您正在创建“Car”的新对象,该对象是“Ridable”。 是的,您正在创建新的“汽车”对象。

    现在Ridable定义为“期望 nameOfTheCar 给你 Car 实例通过 getCar() 方法”,而这正是 "Car::new" 正在做。

    Car::new 
    

    在本例中,与(分配给Ridable的)相同

    carName -> new Car(carName)
    

    现在,使用lambda包装上述行为,即Java7,如下所示:

    Rideable rideable = new Rideable() {
        @Override
        public Car getCar(String carName ) {
            return new Car(carName);
        }
    };
    

    现在假设您有另一个接口

    @FunctionalInterface
    interface SelfRideable {
        Car getSelfDriven();
    }
    

    现在如果你这样做了

    SelfRideable selfDriven = Car::new;
    

    然后它就不会编译了,因为现在它没有任何参数,也没有方法( getSelfDriven() ). 要使其工作,您需要有默认构造函数。