Reputation: 23498
I was testing the capabilities and abuse of the default keyword in Java. I decided to test multiple inheritance and what would happen if I declared two variables of the same name and signature in an interface and in the class implementing the interface.
Code: http://ideone.com/mKJjst
import java.util.*;
import java.lang.*;
import java.io.*;
interface Foo {
default void Meh() {
System.out.println("Foo.Meh");
}
}
interface Bar {
String test="t";
default String getTest(){
return test;
}
default void doTest(){
System.out.println("Bar.doTest: -- getTest" + getTest());
}
default void Bar() {
System.out.println("Bar.Bar()");
String blahh=test;
}
static void Sup(){
System.out.println("Bar.Sup -- Test: "+test);
}
default void Meh() {
System.out.println("Bar.Meh -- Test: "+test);
}
default void mega() {
Meh();
}
}
abstract class Test {
public void Meh() {
System.out.println("Test.Meh");
}
}
class Ideone extends Test implements Foo, Bar {
public static void main (String[] args) throws java.lang.Exception
{
new Ideone().Meh();
blah();
}
public void Meh() {
Bar.super.Bar();
Bar.super.Meh();
System.out.println("Ideone.Meh -- Test: "+test);
Foo.super.Meh();
super.Meh();
Bar hack = new Bar(){
public static final String test="over";
public String getTest(){
System.out.println("Ideone.Meh.hack.super.test: " + Bar.super.getTest());
return test;
}
public void Meh(){
System.out.println("Ideone.Meh.hack.Meh()");
func();
Bar.Sup();
Bar.super.Meh();
}
public void func(){
System.out.println("Ideone.Meh.hack.func -- Test: "+test);
}
};
hack.Meh();
System.out.println("Ideone.Meh.hack.test: " + hack.test);
hack.mega();
hack.doTest();
}
public static void blah() {
}
}
Results:
Bar.Bar()
Bar.Meh -- Test: t
Ideone.Meh -- Test: t
Foo.Meh
Test.Meh
Ideone.Meh.hack.Meh()
Ideone.Meh.hack.func -- Test: over
Bar.Sup -- Test: t
Bar.Meh -- Test: t
Ideone.Meh.hack.test: t
Ideone.Meh.hack.Meh()
Ideone.Meh.hack.func -- Test: over
Bar.Sup -- Test: t
Bar.Meh -- Test: t
Ideone.Meh.hack.super.test: t
Bar.doTest: -- getTestover
How is it possible that Bar hack
can have a variable called test
with a value of over
and at the same time have a variable called test
with a value of t
?
Also, is Bar hack = new Bar();
inheriting from itself? If hack is an instance of Bar
, how can it have a super
that is of type Bar
and contains a different test
?
What's actually going on here?
Upvotes: 4
Views: 306
Reputation: 21883
1.
How is it possible that Bar hack can have a variable called test with a value of over and at the same time have a variable called test with a value of t?
This statement is false. In java there are classes and instances of classes. A static constant/variable belongs to the class not to the instances of that class. So
Bar hack = new Bar() {
public static final String test="over";
Above test
constant belongs to Bar annonymous class (Bar$1.class) not Bar.class. test
constant with value "t"
is what belongs to Bar.class. So using it within func
method the will print the closest scoped variable which is obviously has the value "over"
public void func(){
System.out.println("Ideone.Meh.hack.func -- Test: "+test);
}
So if you want to print Bar.test
since test is a public static constant that belongs to Bar you can use the follow code.
public void func(){
System.out.println("Ideone.Meh.hack.func -- Test: "+Bar.test);
}
2.
Also, is Bar hack = new Bar(); inheriting from itself? If hack is an instance of Bar, how can it have a super that is of type Bar and contains a different test?
As I said earlier following declaration results in an annonymous inner class which implements Bar.
Bar hack = new Bar(){
public static final String test="over";
public String getTest(){
System.out.println("Ideone.Meh.hack.super.test: " + Bar.super.getTest());
return test;
}
public void Meh(){
System.out.println("Ideone.Meh.hack.Meh()");
func();
Bar.Sup();
Bar.super.Meh();
}
public void func(){
System.out.println("Ideone.Meh.hack.func -- Test: "+test);
}
};
True hack is a Bar but test is a static constant which means it doesn't belong to the class instance but to the class.
Upvotes: 1
Reputation: 5569
How is it possible that
Bar hack
can have a variable calledtest
with a value ofover
and at the same time have a variable calledtest
with a value oft
?
Interfaces can only declare constants (static final
is implicit). Therefore the object Bar hack
doesn't have any [instance] variables, it just has scope access to two static final variables that happen to have the same name, declared by an interface and a class respectively.
Also, is
Bar hack = new Bar();
inheriting from itself? If hack is an instance ofBar
, how can it have asuper
that is of typeBar
and contains a differenttest
?
Actually, Bar hack = new Bar() { ... };
. So hack
is in instance of an anonymous inner subclass of Bar
. Yes, this one-off subclass does inherit from class Bar
.
What's actually going on here?
You're learning Java :)
Upvotes: 4