While playing with lambdas for Java 8. I noticed an interesting behaviour when trying to access an interface member variable in three ways.
import java.util.*;
public interface Pet {
String kind ="Pet";
default void interact() { System.out.println(String.format("Wanna buy a %s", this.kind)); }
}
class Frog implements Pet {
public String kind ="Frog";
public void interact() { System.out.println(this.kind); }
}
class Rat implements Pet {
public String kind ="Rat";
public void interact() { System.out.println(this.kind); }
}
public class InternalIteration {
public static void main(String[] args) {
List<Pet> pets = Arrays.asList(new Rat(), new Frog());
System.out.println("Speak method output:");
pets.forEach((Pet p)->{
p.interact();
});
System.out.println("Un-casted class kind member variable:");
pets.forEach((Pet p)->{
System.out.println(p.kind);
});
System.out.println("Casted class kind member variable:");
System.out.println(((Rat)pets.get(0)).kind);
System.out.println(((Frog)pets.get(1)).kind);
}
}
Running this code gives the following result:
Speak method output:
Rat
Frog
Un-casted class kind attribute:
Pet
Pet
Casted class kind attribute:
Rat
Frog
It seems that when accessing the variable through the implementations of the interact
method the variable accessed is the one in the implementation class. However when accessing the public variable directly the interface member variable is returned. Accessing it directly after casting seems to return implementation variable again.
This looks confusing if not inconsistent to me since accessing the interact
method and the kind
public variable returns different results even when operating on the same object.