Brandon
Brandon

Reputation: 23498

Java multiple inheritance duplicate variable declaration?

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

Answers (2)

shazin
shazin

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

gknicker
gknicker

Reputation: 5569

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?

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 of Bar, how can it have a super that is of type Bar and contains a different test?

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

Related Questions