Reputation: 1429
I would like to ask about the following piece of code related to Functional Interfaces. I am confused by:
Rideable rider = Car :: new
Is it creating a Rideable
(interface) or Car
(class) instance?
If it is creating a Car
object, the constructor new Car()
(i.e. with no arguments) should be not existing, then how come this can be valid?
I Have been reading through this tutorial ,but still could not figure it out.
@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");
}
}
Upvotes: 6
Views: 1156
Reputation: 1126
You are creating new object of "Car" which is "Rideable". So yes, you are creating new "Car" object.
Now Rideable is defined as "expecting nameOfTheCar
and gives you Car
instance via getCar()
method" and that is precisely what "Car::new"
is doing.
Car::new
in this example is same as(as its assigned to Rideable)
carName -> new Car(carName)
Now the above behaviour is wrapped using lambda which would be Java7 look something like below:
Rideable rideable = new Rideable() {
@Override
public Car getCar(String carName ) {
return new Car(carName);
}
};
Now let's say you have another interface
@FunctionalInterface
interface SelfRideable {
Car getSelfDriven();
}
And now if you do
SelfRideable selfDriven = Car::new;
Then it would not compile since now it does not have any parameter it its method(getSelfDriven()
). For this to work, you would need to have default constructor.
Upvotes: 1
Reputation: 139029
You are using the Lambda syntax to implement the getCar()
method of the Rideable interface, where the following anonymous class program is omitted using Lambda's concise syntax:
Rideable rideable = new Rideable() {
@Override
public Car getCar(String name) {
return new Car(name);
}
};
This is Java 7 code. You can achieve the same thing using using Lambda expression:
Rideable rider = name -> new Car(name);
Or as in your example, using method reference:
Rideable rider = Car::new;
As a result, the getCar(String)
method of the Rideable object can be used as a new Car(String)
.
And as an answer to your question, you are creating an instance of Car
class that implements the Rideable interface. This is another way you can implement an interface without using implement
keyword.
If you are thinking of:
Car auto = Car("MyCar")::new;
or
Car auto = Car::new;
Car vehicle = auto::getCar("MyCar");
or
Car vehicle = Rideable::new::getCar("MyCar");
All these examples are wrong
approaches. I gave you this examples because these are common mistakes that can be made when we are speaking about Lambda expressions or method reference.
Upvotes: 1
Reputation: 394126
Is it creating a Rideable (interface) or Car (class) instance?
It is creating an instance of (a class that implements) the Rideable
interface.
The Rideable
functional interface has a single method - getCar
- that accepts a String
argument and returns a Car
instance.
The public Car (String name)
constructor accepts a String
argument and produces a Car
instance.
Therefore the method reference Car::new
(which in this case does not refer to a parameter-less constructor) can be used as implementation of the Rideable
interface.
And if it helps to clarify the confusion, here's a lambda expression equivalent to the Car::new
method reference:
Rideable rider = (String s) -> new Car(s);
or
Rideable rider = s -> new Car(s);
Upvotes: 5