I read this question and thought that would easily be solved (not that it isn't solvable without) if one could write:
@Override public String toString() { return super.super.toString(); }
I'm not sure if it is useful in many cases, but I wonder why it isn't and if something like this exists in other languages.
What do you guys think?
EDIT: To clarify: yes I know, that's impossible in Java and I don't really miss it. This is nothing I expected to work and was surprised getting a compiler error. I just had the idea and like to discuss it.
Your code would break if you called a super of a super that had no super. Object oriented programming (which Java is) is all about objects, not functions. If you want task oriented programming, choose C++ or something else.
We can use super keyword to access the data member or field of parent class. It is used if parent class and child class have same fields. In the above example, Animal and Dog both classes have a common property color. If we print color property, it will print the color of current class by default.
Call to super() must be first statement in Derived(Student) Class constructor. If a constructor does not explicitly invoke a superclass constructor, the Java compiler automatically inserts a call to the no-argument constructor of the superclass.
However, using super() is not compulsory. Even if super() is not used in the subclass constructor, the compiler implicitly calls the default constructor of the superclass.
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?
I think Jon Skeet has the correct answer. I'd just like to add that you can access shadowed variables from superclasses of superclasses by casting this
:
interface I { int x = 0; } class T1 implements I { int x = 1; } class T2 extends T1 { int x = 2; } class T3 extends T2 { int x = 3; void test() { System.out.println("x=\t\t" + x); System.out.println("super.x=\t\t" + super.x); System.out.println("((T2)this).x=\t" + ((T2)this).x); System.out.println("((T1)this).x=\t" + ((T1)this).x); System.out.println("((I)this).x=\t" + ((I)this).x); } } class Test { public static void main(String[] args) { new T3().test(); } }
which produces the output:
x= 3 super.x= 2 ((T2)this).x= 2 ((T1)this).x= 1 ((I)this).x= 0
(example from the JLS)
However, this doesn't work for method calls because method calls are determined based on the runtime type of the object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With