Why Is Super.Super.Method(); Not Allowed in Java

Why is super.super.method(); not allowed in Java?

It violates encapsulation. You shouldn't be able to bypass the parent class's behaviour. It makes sense to sometimes be able to bypass your own class's behaviour (particularly from within the same method) but not your parent's. For example, suppose we have a base "collection of items", a subclass representing "a collection of red items" and a subclass of that representing "a collection of big red items". It makes sense to have:

public class Items
{
public void add(Item item) { ... }
}

public class RedItems extends Items
{
@Override
public void add(Item item)
{
if (!item.isRed())
{
throw new NotRedItemException();
}
super.add(item);
}
}

public class BigRedItems extends RedItems
{
@Override
public void add(Item item)
{
if (!item.isBig())
{
throw new NotBigItemException();
}
super.add(item);
}
}

That's fine - RedItems can always be confident that the items it contains are all red. Now suppose we were able to call super.super.add():

public class NaughtyItems extends RedItems
{
@Override
public void add(Item item)
{
// I don't care if it's red or not. Take that, RedItems!
super.super.add(item);
}
}

Now we could add whatever we like, and the invariant in RedItems is broken.

Does that make sense?

Calling super super class method

You can't even use reflection. Something like

Class superSuperClass = this.getClass().getSuperclass().getSuperclass();
superSuperClass.getMethod("foo").invoke(this);

would lead to an InvocationTargetException, because even if you call the foo-Method on the superSuperClass, it will still use C.foo() when you specify "this" in invoke. This is a consequence from the fact that all Java methods are virtual methods.

It seems you need help from the B class (e.g. by defining a superFoo(){ super.foo(); } method).

That said, it looks like a design problem if you try something like this, so it would be helpful to give us some background: Why you need to do this?

Asking super of super

Picked up the most appropriate answer from here by Jon Skeet

You can't - because it would break encapsulation.

You're able to call your superclass's method because it's assumed that you know what breaks encapsulation in your own class, and avoid that... but you don't know what rules your superclass is enforcing - so you can't just bypass an implementation there.

Why is using super to call methods other than the one being overridden not recommended?

Why using super.foo() outside method foo() is a bad idea

It suggests the old method is still needed (and does something different from the child version of the method), in which case you probably shouldn't be overriding it in the first place. The parent method still "makes sense" within the child object.

Two identically named methods both being used within the same object but with different effects sounds like a nightmare for readability. Given that both are being used it seems highly likely that they should be separate methods with different method names making their subtle difference clear.

Why using super.foo() to refer to a method that isn't overridden is a bad idea

This semantically is a very odd thing to write. A parents (non private) methods are the childs methods unless overridden, using super.method() has an identical effect to method() and so it is not surprising you have not seen this mentioned. As you have supposed it is also very likely to cause bugs in the future if you later do override the method.

Similarly to this you can put public on the front of interface methods but it has no effect.

Why you can't use super with static methods

Static methods cannot be overridden, if a parent class and a child class happen to have the same method name that is simply a coincidence as far as the compiler is concerned (although it does hide the static method in the parent class - it does not override it). Given that a static method cannot be overridden using the super keyword to access one becomes meaningless. Furthermore you can access a static method in Foo as

Foo.staticMethod();

When writing an override method, why calling another superclass method is allowed in Java?

So why super call is allowed to call some other methods?

Because your code may need to do that. It's no different, really, from a method calling other methods defined by the same class. Remember that the superclass's methods are part of the current instance. Inheritance is massively tightly-coupled. So any non-private member of the superclass can be used, as it's part of the instance and not hidden from the subclass. (private members are still part of the instance, but are hidden from the subclass unless you [ab]use reflection to expose them.)

It's worth noting that this doesn't have anything to do with these being nested classes; it's true for top-level classes as well.

How do I access the super-super class, in Java? [Mini-example inside]

You can't - and very deliberately. It would violate encapsulation. You'd be skipping whatever B.method wants to do - possibly validating arguments (assuming there were any), enforcing invariants etc.

How could you expect B to keep a consistent view of its world if any derived class can just skip whatever behaviour it's defined?

If the behaviour B provides isn't appropriate for C, it shouldn't extend it. Don't try to abuse inheritance like this.



Related Topics



Leave a reply



Submit