how to understand super in java - java

I encountered a problem that confused me, it is the keyword 'super', my test code is like this:
package test;
public class Parent {
private String name;
public Parent(){
this.name = "parent";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void showName(){
System.out.println(this.name);
}
}
public class Child extends Parent{
public Child(){
this.setName("Child");
}
public void showName(){
System.out.println(super.getClass().toString());
System.out.println(super.toString());
super.showName();
System.out.println(super.getName());
}
}
public class Test {
public static void main(String[] args) {
Child d = new Child();
d.showName();
}
}
so the result is like this:
class test.Child
test.Child#2207d8bb
Child
Child
my understanding about 'super' is that it is a reference to the parent instance of current instance, so my expecting output is like 'Parent', from the result , I am wrong, its like the current instance calls the parent method, and 'super' is not parent instance, is my understanding right ? and is there a way that I can get parent instance only initializing the Child class ?

my understanding about 'super' is that it is a reference to the parent instance of current instance
No - there's no such thing as a "parent instance". When you create an instance, there's only one object created - an instance of Child, which inherits all the fields and methods from Parent as well.
super is used in two ways:
To refer to the superclass implementation of a method, typically when you've overridden the method in the subclass. This is what you're doing in Child.showName - it's calling Parent.showName, but on the same instance (because there is only one instance)
To call a superclass constructor from a subclass constructor

From the javadocs, getClass returns the runtime class of an object.
The runtime class of your object is "Child".
As you did not override getClass() (you can't because it's final), so super.getClass() acts exactly like getClass(). getClass method of the Object class is called.
If you want to print the Parent, call getClass().getSuperclass()

You have used four print statements invoked using Child object:
System.out.println(super.getClass().toString());
Since the getClass() is final method thus it cant be overridden, so when you invoke super.getClass(), you actually invoke the Object class's getClass() which returns the name of the class of the actual invoking object.
System.out.println(super.toString());
Here again the toString() method of Object class is invoked which returns
"getClass().getName() + "#" + Integer.toHexString(hashCode());"
However, if you override this method in your parent class you will definitely get that version executed
super.showName();
this method returns "Child".... here's why: When you create an object of Child class the contructor runs as follows-
public Child(){
super(); // this is implicitly called by the compiler even if you did not write this
this.setName("Child");
}
So following action take place - 1. Parent class's contructor is called which sets the 'name' to 'parent'. 2. Child class's contructor now overwrites this valus with 'Child'.
So the value of instance variable 'name' is 'Child'.
System.out.println(super.getName());
Here as said in point 3 the there is only one object and one instance variable 'name' whose value is 'Child'.

class Animal {
void eat() {
System.out.println("animal : eat");
}
}
class Dog extends Animal {
void eat() {
System.out.println("dog : eat");
}
void anotherEat() {
super.eat();
}
}
public class Test {
public static void main(String[] args) {
Animal a = new Animal();
a.eat();
Dog d = new Dog();
d.eat();
d.anotherEat();
}
}
The output is going to be
animal : eat
dog : eat
animal : eat
The third line is printing "animal:eat" because we are calling super.eat(). If we called this.eat(), it would have printed as "dog:eat".

Related

If parent and child class are having same methods and i am using the reference of parent class to store the object of child class

Parent class
class Animal {
public void sound() {
System.out.println("Grr");
}
}
Child class
class Dog extends Animal {
public void sound() {
System.out.println("Woof");
}
}
Calling class
class Callings {
public static void main(String args[]) {
Animal a = new Dog();
a.sound();
}
}
Output is - "Woof"
My concern is--> I have read till now that if we use the parent class reference and point to object to child class then using the reference of parent class we can only access the data members and methods of the parent class only, if this is true then output of above code should be "Grr". But the output is "Woof" can any one explain why.
Even you are creating and object for Animal but the instance is type of Dog, you can create an instance of a child class and assign to the type of parent.
When you call a method, it should be defined in the parent class and if it is overridden in child then the child method will be called else the parent's method will be called.
You can check the type of the instance by printing the class type of the instance a by using System.out.println(a.getClass().getName()); which will print Dog
Dog knows it is a Dog, even if you call it an Animal.
Check this question for more details.

Why can methods be overriden but attributes can't?

I have a class
public class A {
public String attr ="A attribute";
public void method() {
System.out.println(this+" , "+this.attr);
}
public String toString() {
return("Object A");
}
}
and another class that inherits from it
public class B extends A{
public String attr = "B attribute";
public void method() {
super.method();
}
public String toString() {
return("Object B");
}
}
Note that the method() of B is simply a wrapper for method() of A.
When I run the following code
B b = new B();
b.method();
I get Object B , A attribute as output which means that, this and this.attr accessed different things. Why is that the case?
Shouldn't System.out.println(this) refer to the toString() method of class A ?
By declaring a method with a same name as parent class, you override it, that is, replace the original behaviour. But if you declare a field with a same name, you effectively hide it, making it inaccessible from that subclass, but only by super.field. See oracle docs on variable hiding, as well as using the keyword super. Note that it is not recommended to use variable hiding, as it creates exactly the kind of confusion you're experiencing.
By calling super.method(), printing this results in calling the toString method, which was in fact overridden - so that's the reason why it prints "Object B", as you've called the method on an instance of B. But the this in this.attr actually refers to the parent object, as you're calling the method from the parent class (by super.method()).

Understanding the concept of super?

I'm having trouble wrapping my head around the concept of super(). Java Tutorials gives this example:
public class Superclass {
public void printMethod() {
System.out.println("Printed in Superclass.");
}
}
public class Subclass extends Superclass {
// overrides printMethod in Superclass
public void printMethod() {
super.printMethod();
System.out.println("Printed in Subclass");
}
public static void main(String[] args) {
Subclass s = new Subclass();
s.printMethod();
}
}
But if I am overriding the printMethod, why do I need to invoke the Superclass method? Why can't I just write whatever in the Subclass method of printMethod() and just move on?
There is absolutely no need to call the super.
It just helps you to call the logic contained within super class method if you require that.
Many times you want the exact logic to run and then provide your additional logic.
Overriding always does not mean providing brand new logic. Sometimes you want to provide a slight variation. For e.g., if the method returns a value, then you call the super class method and get the value. Then you make some slight modification in that object using logic in the sub class method and return it back to caller.
You can override it. In that case, the parent method is ignored. super() is used if you want the parent method to be executed in the subclass.
This is used to avoid duplicated code. Let's say you have a class:
public class SuperClass() {
private int var1;
private int var2;
private int var3;
public SuperClass() {
var1 = 1;
var2 = 2;
var3 = 3;
}
}
and a subclass:
public class SubClass() {
private int var1;
private int var2;
private int var3;
private int var4;
public SubClass() {
super();
var4 = 4;
}
}
In this example, you are using super() to invoke superclass constructor (constructor are usually used to initialize members) so you can focus on the SubClass members, and you don't have to repeat all the initialization lines (for var1, var2 and var3).
Basically the super class is the upper most level of the program. When you create a new subclass you must "inherit" from the super class using the keyword 'extends'. This does 2 things; It allows you to use any methods created in the super class, in the subclass and it also allows you overwrite methods in the super class. Basically, if you have one method you want to use in a bunch of classes you use the super class to create it and then the sub-classes can just call the method using standard dot notation.
If you just run this program, Inside PrintMethod of the subclass will call to super class "printMethod" (print "Printed in Superclass") and then execute the things you have written in the sub class method(print "Printed in Subclass").
public void printMethod() {
//super.printMethod(); // comment this line
System.out.println("Printed in Subclass");
}
if you run like this, it will print only the things that you have written in the sub class method.
Idea is, If you want use Super class method information in the sub class, then you can call like Super.MethodName().
Clear Explanation :
public static void main(String[] args) {
Subclass s = new Subclass();
s.printMethod();
}
Subclass s = new Subclass();
(i) when we are creating sub class object what wiill happens?
constructor of subclss will be executed
(ii) Do we have any costructor in sub class (Subclass )
if we have dat will execute..
but we are not having so default costructor will excecute
(iii) what default costructor will have?
Subclass (){
super();
}
(iv) what super() will do?
it calls super class contructor
in super class also we are not having constructor so
will execute default constructor
Superclass(){
super();
}
super class of superclass is Object class
so Object class is the super class of evry class in java
so it will creates object of object class..
object of Object class created
|
and comes to its subclass constructor...//step (iv)
Superclass(){
super(); // executed
}
object of Object class created
|
object of Superclass craeted
so super class constuctror execution also completed so
it will creates Object of SuperClass..
then control comes to its subclass conctructor // step (iii)
so Subclass (){
super(); // executed
}
after completion of subclass constructor it creates the object of subclass
*Important point : after completion of constructor execution
Object of thet class will be created*
object of Object class created
|
object of Superclass craeted
|
object of Subclass craeted
all this happened because of Subclass s = new Subclass();
so when you created object of sub class 3 objects are created..
s.printMethod();
now you are calling a method on subclass object
^
printMethod() is there in super class and sub class
when u r calling a method on sub class object what happens?
(i) it will search for that method in outer most objest: Object of Object class
so now printMethod() is not there in object of object class
(ii) Next its searches in next superclass object ie. object of Superclass
object Superclass object having printMethod() method
(iii) so method found...eventhougth method found controll serches in next sub most object is object of subclass object....
(iv) two methos found in two object but it excecutes sub most object method.
so sub most object is Subclass object...
so it executes the subclass printMethod() method.
Note: when we call a method on object it will executes the sub most objects method if ovverriden.....
now our method is....
public void printMethod() {
super.printMethod();
System.out.println("Printed in Subclass");
}
first line in this method is super.printMethod();
by default super ponts to super class object : object of Superclass
object of Superclass .printMethod() is
public void printMethod() {
System.out.println("Printed in Superclass.");
}
so prints :
Printed in Superclass.
next line is : System.out.println("Printed in Subclass");
so it prints : Printed in Subclass
Note : first while creating object it called super class constructor..
now in method called super class method..
Note:
1.if class not having any constructor jvm assigns default constructor as
ClassName(){
super(); calls super class constructor
}
if class alrdy having constructor
the first line of the constructor should be the super() call.
for example: class A{
int variablea;
A(int a){
variablea=a;
}
public static void main(String[] args) {
A a=new A(2);
}
}
in this example
A(int a){
variablea=a;
} code replaces with
A(int a){
super(); by jvm by default
variablea=a;
}
You can use super in a subclass to refer to its immediate superclass. Super has two general forms.
to call the super class's constructor from the subclass
to access a member of the superclass from the subclass
I'm assuming that you are trying to understand the second one.
An example which might make you understand how super helps in referencing members of the super class:
public class Human {
String name;
int age;
public void printDetails() {
System.out.println("Name:"+name);
System.out.println("Age:"+age);
}
}
public class Student extends Human {
int rollNumber;
String grade;
public void printDetails() {
super.printDetails();
System.out.println("Roll Number:"+rollNumber);
System.out.println("Grade:"+grade);
}
public void printNameAgeAndSayGoodMorning(){
super.printDetails();
System.out.println("Good morning!");
}
public static void main(String[] args) {
Student s = new Student();
s.name="MyName";
s.age=27;
s.rollNumber=3;
s.grade="A+";
s.printDetails();
System.out.println(); //just an empty line
s.printNameAgeAndSayGoodMorning();
}
}
I avoided constructors or any getter/setter methods for simplicity.
In this example, do you think you really have to "just write whatever in the Subclass" instead of reusing the printDetails() method available in the super class?

What is method hiding in Java? Even the JavaDoc explanation is confusing

Javadoc says:
the version of the hidden method that gets invoked is the one in the superclass, and the version of the overridden method that gets invoked is the one in the subclass.
doesn't ring a bell to me. Any clear example showing the meaning of this will be highly appreciated.
public class Animal {
public static void foo() {
System.out.println("Animal");
}
}
public class Cat extends Animal {
public static void foo() { // hides Animal.foo()
System.out.println("Cat");
}
}
Here, Cat.foo() is said to hide Animal.foo(). Hiding does not work like overriding, because static methods are not polymorphic. So the following will happen:
Animal.foo(); // prints Animal
Cat.foo(); // prints Cat
Animal a = new Animal();
Animal b = new Cat();
Cat c = new Cat();
Animal d = null;
a.foo(); // should not be done. Prints Animal because the declared type of a is Animal
b.foo(); // should not be done. Prints Animal because the declared type of b is Animal
c.foo(); // should not be done. Prints Cat because the declared type of c is Cat
d.foo(); // should not be done. Prints Animal because the declared type of d is Animal
Calling static methods on instances rather than classes is a very bad practice, and should never be done.
Compare this with instance methods, which are polymorphic and are thus overridden. The method called depends on the concrete, runtime type of the object:
public class Animal {
public void foo() {
System.out.println("Animal");
}
}
public class Cat extends Animal {
public void foo() { // overrides Animal.foo()
System.out.println("Cat");
}
}
Then the following will happen:
Animal a = new Animal();
Animal b = new Cat();
Cat c = new Cat();
Animal d = null;
a.foo(); // prints Animal
b.foo(); // prints Cat
c.foo(); // prints Cat
d.foo(): // throws NullPointerException
First of all What is meant by method Hiding?
Method hiding means subclass has defined a class method with the same signature as a class method in the superclass. In that case the method of superclass is hidden by the subclass. It signifies that : The version of a method that is executed will NOT be determined by the object that is used to invoke it. In fact it will be determined by the type of reference variable used to invoke the method.
What is meant by method overriding?
Method overriding means subclass had defined an instance method with the same signature and return type( including covariant type) as the instance method in superclass. In that case method of superclass is overridden(replaced) by the subclass. It signifies that: The version of method that is executed will be determined by the object that is used to invoke it. It will not be determined by the type of reference variable used to invoke the method.
Why can't static methods be overridden?
Because, static methods are resolved statically (i.e. at compile time) based on the class they are called on and not dynamically as in the case with instance methods which are resolved polymorphically based on the runtime type of the object.
How should static methods be accessed?
Static methods should be accessed in static way. i.e. by the name of class itself rather than using an instance.
Here is the short Demo for method overriding and hiding:
class Super
{
public static void foo(){System.out.println("I am foo in Super");}
public void bar(){System.out.println("I am bar in Super");}
}
class Child extends Super
{
public static void foo(){System.out.println("I am foo in Child");}//Hiding
public void bar(){System.out.println("I am bar in Child");}//Overriding
public static void main(String[] args)
{
Super sup = new Child();//Child object is reference by the variable of type Super
Child child = new Child();//Child object is referenced by the variable of type Child
sup.foo();//It will call the method of Super.
child.foo();//It will call the method of Child.
sup.bar();//It will call the method of Child.
child.bar();//It will call the method of Child again.
}
}
Output is
I am foo in Super
I am foo in Child
I am bar in Child
I am bar in Child
Clearly, as specified, since foo is the class method so the version of foo invoked will be determined by the type of reference variable (i.e Super or Child) referencing the object of Child. If it is referenced by Super variable then foo of Super is called. And if it is referenced by Child variable then foo of Child is called.
Whereas,
Since bar is the instance method so the version of bar invoked is solely determined by the object(i.e Child) that is used to invoke it. No matter via which reference variable (Super or Child) it is called , the method which is going to be called is always of Child.
To overwrite a method means that whenever the method is called on an object of the derived class, the new implementation will be called.
To hide a method means that an unqualified call to that name in the scope of this class (i.e. in the body of any of its methods, or when qualified with the name of this class) will now call a completely different function, requiring a qualification to access the static method of the same name from the parent class.
More description Java Inheritance: Overwritten or hidden methods
If a subclass defines a class method with the same signature as a class method in the superclass, the method in the subclass hides the one in the superclass.
Hidden methods are in Static context, I believe. Static methods are not overridden, per se, because the resolution of method calls done by the compiler at the compile time itself. So, if you define a static method in the base class with the same signature as that one present in the parent class, then the method in the subclass hides the method inherited from super class.
class Foo {
public static void method() {
System.out.println("in Foo");
}
}
class Bar extends Foo {
public static void method() {
System.out.println("in Bar");
}
}
For example you can override instance methods in a super class but not static.
Hiding is Parent class has a static method named Foo and the sub class also has a static method called Foo.
Another scenario is the parent has a static method named Cat and the sub class has an instance method named Cat. (static and instance with the same signature can't intermix).
public class Animal {
public static String getCat() { return "Cat"; }
public boolean isAnimal() { return true; }
}
public class Dog extends Animal {
// Method hiding
public static String getCat() { }
// Not method hiding
#Override
public boolean isAnimal() { return false; }
}
class P
{
public static void m1()
{
System.out.println("Parent");
}
}
class C extends P
{
public static void m1()
{
System.out.println("Child");
}
}
class Test{
public static void main(String args[])
{
Parent p=new Parent();//Parent
Child c=new Child(); //Child
Parent p=new Child(); //Parent
}
}
If the both parent and child class method are static the compiler is responsible for method resolution based on reference type
class Parent
{
public void m1()
{
System.out.println("Parent");
}}
class Child extends Parent
{
public void m1()
{
System.out.println("Child")
}
}
class Test
{
public static void main(String args[])
{
Parent p=new Parent(); //Parent
Child c=new Child(); //Child
Parent p=new Child(); //Child
}
}
If both method are not static jvm is responsible for method resolution based on run time object
When super/parent class and sub/child class contains same static method including same parameters and signature. The method in the super class will be hidden by the method in sub class. This is known as method hiding.
Example:1
class Demo{
public static void staticMethod() {
System.out.println("super class - staticMethod");
}
}
public class Sample extends Demo {
public static void main(String args[] ) {
Sample.staticMethod(); // super class - staticMethod
}
}
Example:2 - Method Hiding
class Demo{
public static void staticMethod() {
System.out.println("super class - staticMethod");
}
}
public class Sample extends Demo {
public static void staticMethod() {
System.out.println("sub class - staticMethod");
}
public static void main(String args[] ) {
Sample.staticMethod(); // sub class - staticMethod
}
}
first of all always class a static method using class name.
if function is static then it is method hiding whereas function is non static then method is overriding.

Overriding vs Hiding Java - Confused

I'm confused on how overriding differs from hiding in Java. Can anyone provide more details on how these differ? I read the Java Tutorial but the sample code still left me confused.
To be more clear, I understand overriding well. My issue is that I don't see how hiding is any different, except for the fact that one is at the instance level while the other is at the class level.
Looking at the Java tutorial code:
public class Animal {
public static void testClassMethod() {
System.out.println("Class" + " method in Animal.");
}
public void testInstanceMethod() {
System.out.println("Instance " + " method in Animal.");
}
}
Then we have a subclass Cat:
public class Cat extends Animal {
public static void testClassMethod() {
System.out.println("The class method" + " in Cat.");
}
public void testInstanceMethod() {
System.out.println("The instance method" + " in Cat.");
}
public static void main(String[] args) {
Cat myCat = new Cat();
Animal myAnimal = myCat;
Animal.testClassMethod();
myAnimal.testInstanceMethod();
}
}
Then they say:
The output from this program is as follows:
Class method in Animal.
The instance method in Cat.
To me, the fact that calling a class method testClassMethod() directly from the Animal class executes the method in Animal class is pretty obvious, nothing special there. Then they call the testInstanceMethod() from a reference to myCat, so again pretty obvious that the method executed then is the one in the instance of Cat.
From what I see, the call hiding behaves just like overriding, so why make that distinction? If I run this code using the classes above:
Cat.testClassMethod();
I'll get:
The class method in Cat.
But if I remove the testClassMethod() from Cat, then I'll get:
The class method in Animal.
Which shows me that writing a static method, with the same signature as in the parent, in a subclass pretty much does an override.
Hopefully I'm making clear my where I'm confused and someone can shed some light. Thanks very much in advance!
Overriding basically supports late binding. Therefore, it's decided at run time which method will be called. It is for non-static methods.
Hiding is for all other members (static methods, instance members, static members). It is based on the early binding. More clearly, the method or member to be called or used is decided during compile time.
In your example, the first call, Animal.testClassMethod() is a call to a static method, hence it is pretty sure which method is going to be called.
In the second call, myAnimal.testInstanceMethod(), you call a non-static method. This is what you call run-time polymorphism. It is not decided until run time which method is to be called.
For further clarification, read Overriding Vs Hiding.
Static methods are hidden, non-static methods are overriden.
The difference is notable when calls are not qualified "something()" vs "this.something()".
I can't really seem to put it down on words, so here goes an example:
public class Animal {
public static void something() {
System.out.println("animal.something");
}
public void eat() {
System.out.println("animal.eat");
}
public Animal() {
// This will always call Animal.something(), since it can't be overriden, because it is static.
something();
// This will call the eat() defined in overriding classes.
eat();
}
}
public class Dog extends Animal {
public static void something() {
// This method merely hides Animal.something(), making it uncallable, but does not override it, or alter calls to it in any way.
System.out.println("dog.something");
}
public void eat() {
// This method overrides eat(), and will affect calls to eat()
System.out.println("dog.eat");
}
public Dog() {
super();
}
public static void main(String[] args) {
new Dog();
}
}
OUTPUT:
animal.something
dog.eat
This is the difference between overrides and hiding,
If both method in parent class and child class are an instance method, it called overrides.
If both method in parent class and child class are static method, it called hiding.
One method cant be static in parent and as an instance in the child. and visa versa.
If I understand your question properly then the answer is "you already are overriding".
"Which shows me that writing a static method, with the same name as in the parent, in a subclass pretty much does an override."
If you write a method in a subclass with exactly the same name as a method in a superclass it will override the superclass's method. The #Override annotation is not required to override a method. It does however make your code more readable and forces the compiler to check that you are actually overriding a method (and didn't misspell the subclass method for example).
Overriding happens only with instance methods.
When the type of the reference variable is Animal and the object is Cat then the instance method is called from Cat (this is overriding). For the same acat object the class method of Animal is used.
public static void main(String[] args) {
Animal acat = new Cat();
acat.testInstanceMethod();
acat.testClassMethod();
}
Output is:
The instance method in Cat.
Class method in Animal.
public class First {
public void Overriding(int i) { /* will be overridden in class Second */ }
public static void Hiding(int i) { /* will be hidden in class Second
because it's static */ }
}
public class Second extends First {
public void Overriding(int i) { /* overridden here */ }
public static void Hiding(int i) { /* hides method in class First
because it's static */ }
}
The rule for memorizing is simple: a method in an extending class
can't change static to void and
can't change void to static.
It will cause of compile-error.
But if void Name is changed to void Name it's Overriding.
And if static Name is changed to static Name it's Hiding. (Both the static method of the subclass as well as the one of the superclass can be called, depending on the type of the reference used to call the method.)
In this code snippet I use 'private' access modifier instead of 'static' to show you difference between hiding methods and overriding methods.
class Animal {
// Use 'static' or 'private' access modifiers to see how method hiding work.
private void testInstancePrivateMethod(String source) {
System.out.println("\tAnimal: instance Private method calling from "+source);
}
public void testInstanceMethodUsingPrivateMethodInside() {
System.out.println("\tAnimal: instance Public method with using of Private method.");
testInstancePrivateMethod( Animal.class.getSimpleName() );
}
// Use default, 'protected' or 'public' access modifiers to see how method overriding work.
protected void testInstanceProtectedMethod(String source) {
System.out.println("\tAnimal: instance Protected method calling from "+source);
}
public void testInstanceMethodUsingProtectedMethodInside() {
System.out.println("\tAnimal: instance Public method with using of Protected method.");
testInstanceProtectedMethod( Animal.class.getSimpleName() );
}
}
public class Cat extends Animal {
private void testInstancePrivateMethod(String source) {
System.out.println("Cat: instance Private method calling from " + source );
}
public void testInstanceMethodUsingPrivateMethodInside() {
System.out.println("Cat: instance Public method with using of Private method.");
testInstancePrivateMethod( Cat.class.getSimpleName());
System.out.println("Cat: and calling parent after:");
super.testInstanceMethodUsingPrivateMethodInside();
}
protected void testInstanceProtectedMethod(String source) {
System.out.println("Cat: instance Protected method calling from "+ source );
}
public void testInstanceMethodUsingProtectedMethodInside() {
System.out.println("Cat: instance Public method with using of Protected method.");
testInstanceProtectedMethod(Cat.class.getSimpleName());
System.out.println("Cat: and calling parent after:");
super.testInstanceMethodUsingProtectedMethodInside();
}
public static void main(String[] args) {
Cat myCat = new Cat();
System.out.println("----- Method hiding -------");
myCat.testInstanceMethodUsingPrivateMethodInside();
System.out.println("\n----- Method overriding -------");
myCat.testInstanceMethodUsingProtectedMethodInside();
}
}
Output:
----- Method hiding -------
Cat: instance Public method with using of Private method.
Cat: instance Private method calling from Cat
Cat: and calling parent after:
Animal: instance Public method with using of Private method.
Animal: instance Private method calling from Animal
----- Method overriding -------
Cat: instance Public method with using of Protected method.
Cat: instance Protected method calling from Cat
Cat: and calling parent after:
Animal: instance Public method with using of Protected method.
Cat: instance Protected method calling from Animal
I think this is not yet fully explained.
Please see the following example.
class Animal {
public static void testClassMethod() {
System.out.println("The static method in Animal");
}
public void testInstanceMethod() {
System.out.println("The instance method in Animal");
}
}
public class Cat extends Animal {
public static void testClassMethod() {
System.out.println("The static method in Cat");
}
public void testInstanceMethod() {
System.out.println("The instance method in Cat");
}
public static void main(String[] args) {
Animal myCat = new Cat();
Cat myCat2 = new Cat();
myCat.testClassMethod();
myCat2.testClassMethod();
myCat.testInstanceMethod();
myCat2.testInstanceMethod();
}
}
The output will be as follows.
The static method in Animal
The static method in Cat
The instance method in Cat
The instance method in Cat
Based on my recent Java studies
method overriding, when the subclass have the same method with the same signature in the subclass.
Method hiding, when the subclass have the same method name, but different parameter. In this case, you're not overriding the parent method, but hiding it.
Example from OCP Java 7 book, page 70-71:
public class Point {
private int xPos, yPos;
public Point(int x, int y) {
xPos = x;
yPos = y;
}
public boolean equals(Point other){
.... sexy code here ......
}
public static void main(String []args) {
Point p1 = new Point(10, 20);
Point p2 = new Point(50, 100);
Point p3 = new Point(10, 20);
System.out.println("p1 equals p2 is " + p1.equals(p2));
System.out.println("p1 equals p3 is " + p1.equals(p3));
//point's class equals method get invoked
}
}
but if we write the following main:
public static void main(String []args) {
Object p1 = new Point(10, 20);
Object p2 = new Point(50, 100);
Object p3 = new Point(10, 20);
System.out.println("p1 equals p2 is " + p1.equals(p2));
System.out.println("p1 equals p3 is " + p1.equals(p3));
//Object's class equals method get invoked
}
In the second main, we using the Object class as static type, so when we calling the equal method in Point object, it's waiting a Point class to arrive as a parameter,but Object coming. So the Object class equals method getting run, because we have an equals(Object o) there. In this case, the Point's class equals dosen't overrides, but hides the Object class equals method.
public class Parent {
public static void show(){
System.out.println("Parent");
}
}
public class Child extends Parent{
public static void show(){
System.out.println("Child");
}
}
public class Main {
public static void main(String[] args) {
Parent parent=new Child();
parent.show(); // it will call parent show method
}
}
// We can call static method by reference ( as shown above) or by using class name (Parent.show())
The linked java tutorial page explains the concept of overriding and hiding
An instance method in a subclass with the same signature (name, plus the number and the type of its parameters) and return type as an instance method in the superclass overrides the superclass's method.
If a subclass defines a static method with the same signature as a static method in the superclass, then the method in the subclass hides the one in the superclass.
The distinction between hiding a static method and overriding an instance method has important implications:
The version of the overridden instance method that gets invoked is the one in the subclass.
The version of the hidden static method that gets invoked depends on whether it is invoked from the superclass or the subclass.
Coming back to your example:
Animal myAnimal = myCat;
/* invokes static method on Animal, expected. */
Animal.testClassMethod();
/* invokes child class instance method (non-static - it's overriding) */
myAnimal.testInstanceMethod();
Above statement does not show hiding yet.
Now change the code as below to get different output:
Animal myAnimal = myCat;
/* Even though myAnimal is Cat, Animal class method is invoked instead of Cat method*/
myAnimal.testClassMethod();
/* invokes child class instance method (non-static - it's overriding) */
myAnimal.testInstanceMethod();
In addition to the examples listed above, here is a small sample code to clarify the distinction between hiding and overriding:
public class Parent {
// to be hidden (static)
public static String toBeHidden() {
return "Parent";
}
// to be overridden (non-static)
public String toBeOverridden() {
return "Parent";
}
public void printParent() {
System.out.println("to be hidden: " + toBeHidden());
System.out.println("to be overridden: " + toBeOverridden());
}
}
public class Child extends Parent {
public static String toBeHidden() {
return "Child";
}
public String toBeOverridden() {
return "Child";
}
public void printChild() {
System.out.println("to be hidden: " + toBeHidden());
System.out.println("to be overridden: " + toBeOverridden());
}
}
public class Main {
public static void main(String[] args) {
Child child = new Child();
child.printParent();
child.printChild();
}
}
The call of child.printParent() outputs:
to be hidden: Parent
to be overridden: Child
The call of child.printChild() outputs:
to be hidden: Child
to be overridden: Child
As wee can see from the outputs above (especially the bold marked outputs), method hiding behaves differently from overriding.
Java allows both hiding and overriding only for methods. The same rule does not apply to variables. Overriding variables is not permitted, so variables can only be hidden (no difference between static or non-static variable). The example below shows how the method getName() is overriden and the variable name is hidden:
public class Main {
public static void main(String[] args) {
Parent p = new Child();
System.out.println(p.name); // prints Parent (since hiding)
System.out.println(p.getName()); // prints Child (since overriding)
}
}
class Parent {
String name = "Parent";
String getName() {
return name;
}
}
class Child extends Parent {
String name = "Child";
String getName() {
return name;
}
}
At runtime the child version of an overridden method is always executed for an instance
regardless of whether the method call is defi ned in a parent or child class method. In this
manner, the parent method is never used unless an explicit call to the parent method is
referenced, using the syntax
ParentClassName.method().
Alternatively, at runtime the parent
version of a hidden method is always executed if the call to the method is defined in the
parent class.
In method overriding, method resolution is done by the JVM on the basis of runtime object. Whereas in method hiding, method resolution is done by the compiler on the basis of reference.
Thus,
If the code would have been written as,
public static void main(String[] args) {
Animal myCat = new Cat();
myCat.testClassMethod();
}
The Output would be as below:
Class method in Animal.
It is called hiding because the compiler hides the super class method implementation, when subclass has the same static method.
Compiler has no restricted visibility for overridden methods and it’s only during runtime that it’s decided which one is used.
This is the difference between overriding and hiding:
Animal a = new Cat();
a.testClassMethod() will call the method in parent class since it is an example of method hiding. The method to be called is determined by the type of the reference variable and decided at compile time.
a.testInstanceMethod() will call the method in child class since it is an example of method overriding. The method to be called is determined by the object which is used to call the method at runtime.
How is static method hiding happening in java?
Cat class is extending Animal class. So in Cat class will have both static methods (i mean Child class's static method and Parent class's static method)
But how JVM hiding Parent static method? How it's dealing in Heap and Stack?

Categories

Resources