Java Inheritance Wrinkle

5 AM July 28, 2004

I discovered something about Java's type system today.

Suppose there are three Java classes, A, B and C. C extends B and B extends A. A is in package p1. B and C are in package p2. A and C are normal public classes, but B is package private. From package p3, can I see that C is a subclass of A?

In other words, given the following classes:


package p1;



public class A {

    public void sayHi() {

        System.out.println("hi");

    }

}


package p2;



class B extends p1.A {

}


package p2;



public class C extends B {

}

Will this code compile (and run)?


package p3;



public class Run {

    public static void main(String[] args) {

        p1.A c = new p2.C();

        c.sayHi();

    }

}

Answer in blue on blue text here: Yes, and I wonder what evil tricks I can pull in my public APIs as a result.

By alang | # | Comments (7)
(Posted to javablogs and Java)

Comments

At 06:44, 28 Jul 2004 Sean Malloy wrote:

I believe C# stops this from happenings by dissallowing any public classes in an assembly to inherit from private/internal classes. Compiler spits an error about inconsistent access or something (I didn't test, but I remember something along those lines)

(#)
At 10:41, 28 Jul 2004 Anders wrote:

Sorry, I cannot see what is wrong.

You could do more control by having class A final - if thats what you want.

Anders

(#)
At 14:20, 28 Jul 2004 Michael Chermside wrote:

I don't understand how this could lead to "evil tricks". What am I missing?

(#)
At 14:31, 28 Jul 2004 Dummy Hejlsberg wrote:

I also cannot see what is wrong.

Private/internal classes never stoped evil doers. Java offers package sealing to stop evil doers:
Seal package p2 - before the evil class C does its thing.

C# offers Windows to welcome evil doers.

(#)
At 01:29, 29 Jul 2004 Alan Green wrote:

It's not that anything is wrong, I am just drawing attention to a "wrinkle". A wrinkle is something that is only a little out of the ordinary, but which works in a strange way or whose legality is non-obvious. Every complex system has wrinkles, and I enjoy both reading about and finding them.

As for evil tricks... they would be based around treating instances of C as instances of A, when it is not at all clear from the public API that C is an indirect subclass of A.

(#)
At 03:49, 29 Jul 2004 Bernard Choi wrote:

Greetings,

From what I can tell, C is a subclass of A, albeit indirect. When I look at a javadoc, it lists all the parent classes, all the way to java.lang.Object .

What's the significance of it being indirectly subclassed, and what tricks can result from that ?

In one of my projects, I intentionally designed by base class methods to be static protected, so that the user of the classes had to intentionally subclass the base class to gain access to them.

(#)
At 03:50, 29 Jul 2004 Bernard Choi wrote:

designed by base class -> designed my base class

(#)

Add Comment




(Not displayed)






(Leave blank line between paragraphs. URLs converted to links. HTML stripped. Indented source code will be formatted with <pre> tags.)




© 2003-2006 Alan Green