Why do these two code samples produce different outputs? - java

Sample 1:
class Animal {
public static void saySomething() { System.out.print(" Gurrr!");
}
}
class Cow extends Animal {
public static void saySomething() {
System.out.print(" Moo!");
}
public static void main(String [] args) {
Animal [] animals = {new Animal(), new Cow()};
for( Animal a : animals) {
a.saySomething();
}
new Cow().saySomething();
}
}
Output is:
Gurrr! Gurrr! Moo!
Sample 2:
class Animal {
public void saySomething() { System.out.print(" Gurrr!");
}
}
class Cow extends Animal {
public void saySomething() {
System.out.print(" Moo!");
}
public static void main(String [] args) {
Animal [] animals = {new Animal(), new Cow()};
for( Animal a : animals) {
a.saySomething();
}
new Cow().saySomething();
}
}
Output:
Gurrr! Moo! Moo!
I just don't understand why making saySomething non-static causes the second call to saySomething invoke the Cow version instead of the Animal version. My understanding was that Gurrr! Moo! Moo! would be the output in either case.

When you call saySomething() on an animal, the actual type of the animal doesn't count because saySomething() is static.
Animal cow = new Cow();
cow.saySomething();
is the same as
Animal.saySomething();
A JLS example :
When a target reference is computed and then discarded because the invocation mode is static, the reference is not examined to see whether it is null:
class Test {
static void mountain() {
System.out.println("Monadnock");
}
static Test favorite(){
System.out.print("Mount ");
return null;
}
public static void main(String[] args) {
favorite().mountain();
}
}
which prints:
Mount Monadnock
Here favorite returns null, yet no NullPointerException is thrown.
Resources :
JLS - Is the Chosen Method Appropriate?
On the same topic :
Java Static confusion

You cannot override static methods with the same signature in subclasses, just hide them.
For class methods, the runtime system invokes the method defined in the compile-time type of the reference on which the method is called. For instance methods, the runtime system invokes the method defined in the runtime type of the reference on which the method is called.
http://life.csu.edu.au/java-tut/java/javaOO/override.html

Some of the known Overriding "PITFALLS"
static methods cannot be overridden
private methods cannot be overridden
This explains the output.

static methods are bound to their class at compile time and cannot be used polymorphically. When you declare a "static" method on Animal, it is forever bound to the Animal class and cannot be overridden. Static methods are bound to the Class object, not an instance of the Class.
Regular methods are bound at runtime and so the JVM can look at your call to "saySomething" and attempt to determine if you're passing around a subclass of Animal and if so, has it overridden the saySomething() method. Regular methods are bound to an instance of an object, not to the Class itself.
This is also why you could never do this:
class Animal
{
public abstract static void saySomething();
}
Since "static" means "bound at compile time", it never makes sense for something to be static and abstract.

Static methods are tied to the "Class", not the "Instance" of the object.
Since you are referring to an "Animal" and calling the static method saySomething(). It will always make the call to "Animal" unless you are referring to a Cow.

Related

Is Java method overloading is static binding? [duplicate]

I'm currently doing an assignment for one of my classes, and in it, I have to give examples, using Java syntax, of static and dynamic binding.
I understand the basic concept, that static binding happens at compile time and dynamic binding happens at runtime, but I can't figure out how they actually work specifically.
I found an example of static binding online that gives this example:
public static void callEat(Animal animal) {
System.out.println("Animal is eating");
}
public static void callEat(Dog dog) {
System.out.println("Dog is eating");
}
public static void main(String args[])
{
Animal a = new Dog();
callEat(a);
}
And that this would print "animal is eating" because the call to callEat uses static binding, but I'm unsure as to why this is considered static binding.
So far none of the sources I've seen have managed to explain this in a way that I can follow.
From Javarevisited blog post:
Here are a few important differences between static and dynamic binding:
Static binding in Java occurs during compile time while dynamic binding occurs during runtime.
private, final and static methods and variables use static binding and are bonded by compiler while virtual methods are bonded during runtime based upon runtime object.
Static binding uses Type (class in Java) information for binding while dynamic binding uses object to resolve binding.
Overloaded methods are bonded using static binding while overridden methods are bonded using dynamic binding at runtime.
Here is an example which will help you to understand both static and dynamic binding in Java.
Static Binding Example in Java
public class StaticBindingTest {
public static void main(String args[]) {
Collection c = new HashSet();
StaticBindingTest et = new StaticBindingTest();
et.sort(c);
}
//overloaded method takes Collection argument
public Collection sort(Collection c) {
System.out.println("Inside Collection sort method");
return c;
}
//another overloaded method which takes HashSet argument which is sub class
public Collection sort(HashSet hs) {
System.out.println("Inside HashSet sort method");
return hs;
}
}
Output: Inside Collection sort method
Example of Dynamic Binding in Java
public class DynamicBindingTest {
public static void main(String args[]) {
Vehicle vehicle = new Car(); //here Type is vehicle but object will be Car
vehicle.start(); //Car's start called because start() is overridden method
}
}
class Vehicle {
public void start() {
System.out.println("Inside start method of Vehicle");
}
}
class Car extends Vehicle {
#Override
public void start() {
System.out.println("Inside start method of Car");
}
}
Output: Inside start method of Car
Connecting a method call to the method body is known as Binding. As Maulik said "Static binding uses Type(Class in Java) information for binding while Dynamic binding uses Object to resolve binding." So this code :
public class Animal {
void eat() {
System.out.println("animal is eating...");
}
}
class Dog extends Animal {
public static void main(String args[]) {
Animal a = new Dog();
a.eat(); // prints >> dog is eating...
}
#Override
void eat() {
System.out.println("dog is eating...");
}
}
Will produce the result: dog is eating... because it is using the object reference to find which method to use. If we change the above code to this:
class Animal {
static void eat() {
System.out.println("animal is eating...");
}
}
class Dog extends Animal {
public static void main(String args[]) {
Animal a = new Dog();
a.eat(); // prints >> animal is eating...
}
static void eat() {
System.out.println("dog is eating...");
}
}
It will produce : animal is eating... because it is a static method, so it is using Type (in this case Animal) to resolve which static method to call. Beside static methods private and final methods use the same approach.
Well in order to understand how static and dynamic binding actually works? or how they are identified by compiler and JVM?
Let's take below example where Mammal is a parent class which has a method speak() and Human class extends Mammal, overrides the speak() method and then again overloads it with speak(String language).
public class OverridingInternalExample {
private static class Mammal {
public void speak() { System.out.println("ohlllalalalalalaoaoaoa"); }
}
private static class Human extends Mammal {
#Override
public void speak() { System.out.println("Hello"); }
// Valid overload of speak
public void speak(String language) {
if (language.equals("Hindi")) System.out.println("Namaste");
else System.out.println("Hello");
}
#Override
public String toString() { return "Human Class"; }
}
// Code below contains the output and bytecode of the method calls
public static void main(String[] args) {
Mammal anyMammal = new Mammal();
anyMammal.speak(); // Output - ohlllalalalalalaoaoaoa
// 10: invokevirtual #4 // Method org/programming/mitra/exercises/OverridingInternalExample$Mammal.speak:()V
Mammal humanMammal = new Human();
humanMammal.speak(); // Output - Hello
// 23: invokevirtual #4 // Method org/programming/mitra/exercises/OverridingInternalExample$Mammal.speak:()V
Human human = new Human();
human.speak(); // Output - Hello
// 36: invokevirtual #7 // Method org/programming/mitra/exercises/OverridingInternalExample$Human.speak:()V
human.speak("Hindi"); // Output - Namaste
// 42: invokevirtual #9 // Method org/programming/mitra/exercises/OverridingInternalExample$Human.speak:(Ljava/lang/String;)V
}
}
When we compile the above code and try to look at the bytecode using javap -verbose OverridingInternalExample, we can see that compiler generates a constant table where it assigns integer codes to every method call and byte code for the program which I have extracted and included in the program itself (see the comments below every method call)
By looking at above code we can see that the bytecodes of humanMammal.speak(), human.speak() and human.speak("Hindi") are totally different (invokevirtual #4, invokevirtual #7, invokevirtual #9) because the compiler is able to differentiate between them based on the argument list and class reference. Because all of this get resolved at compile time statically that is why Method Overloading is known as Static Polymorphism or Static Binding.
But bytecode for anyMammal.speak() and humanMammal.speak() is same (invokevirtual #4) because according to compiler both methods are called on Mammal reference.
So now the question comes if both method calls have same bytecode then how does JVM know which method to call?
Well, the answer is hidden in the bytecode itself and it is invokevirtual instruction set. JVM uses the invokevirtual instruction to invoke Java equivalent of the C++ virtual methods. In C++ if we want to override one method in another class we need to declare it as virtual, But in Java, all methods are virtual by default because we can override every method in the child class (except private, final and static methods).
In Java, every reference variable holds two hidden pointers
A pointer to a table which again holds methods of the object and a pointer to the Class object. e.g. [speak(), speak(String) Class object]
A pointer to the memory allocated on the heap for that object’s data e.g. values of instance variables.
So all object references indirectly hold a reference to a table which holds all the method references of that object. Java has borrowed this concept from C++ and this table is known as virtual table (vtable).
A vtable is an array like structure which holds virtual method names and their references on array indices. JVM creates only one vtable per class when it loads the class into memory.
So whenever JVM encounter with a invokevirtual instruction set, it checks the vtable of that class for the method reference and invokes the specific method which in our case is the method from a object not the reference.
Because all of this get resolved at runtime only and at runtime JVM gets to know which method to invoke, that is why Method Overriding is known as Dynamic Polymorphism or simply Polymorphism or Dynamic Binding.
You can read it more details on my article How Does JVM Handle Method Overloading and Overriding Internally.
The compiler only knows that the type of "a" is Animal; this happens at compile time, because of which it is called static binding (Method overloading). But if it is dynamic binding then it would call the Dog class method. Here is an example of dynamic binding.
public class DynamicBindingTest {
public static void main(String args[]) {
Animal a= new Dog(); //here Type is Animal but object will be Dog
a.eat(); //Dog's eat called because eat() is overridden method
}
}
class Animal {
public void eat() {
System.out.println("Inside eat method of Animal");
}
}
class Dog extends Animal {
#Override
public void eat() {
System.out.println("Inside eat method of Dog");
}
}
Output:
Inside eat method of Dog
There are three major differences between static and dynamic binding while designing the compilers and how variables and procedures are transferred to the runtime environment.
These differences are as follows:
Static Binding: In static binding three following problems are discussed:
Definition of a procedure
Declaration of a name(variable, etc.)
Scope of the declaration
Dynamic Binding: Three problems that come across in the dynamic binding are as following:
Activation of a procedure
Binding of a name
Lifetime of a binding
With the static method in the parent and child class: Static Binding
public class test1 {
public static void main(String args[]) {
parent pc = new child();
pc.start();
}
}
class parent {
static public void start() {
System.out.println("Inside start method of parent");
}
}
class child extends parent {
static public void start() {
System.out.println("Inside start method of child");
}
}
// Output => Inside start method of parent
Dynamic Binding :
public class test1 {
public static void main(String args[]) {
parent pc = new child();
pc.start();
}
}
class parent {
public void start() {
System.out.println("Inside start method of parent");
}
}
class child extends parent {
public void start() {
System.out.println("Inside start method of child");
}
}
// Output => Inside start method of child
All answers here are correct but i want to add something which is missing.
when you are overriding a static method, it looks like we are overriding it but actually it is not method overriding. Instead it is called method hiding. Static methods cannot be overridden in Java.
Look at below example:
class Animal {
static void eat() {
System.out.println("animal is eating...");
}
}
class Dog extends Animal {
public static void main(String args[]) {
Animal a = new Dog();
a.eat(); // prints >> animal is eating...
}
static void eat() {
System.out.println("dog is eating...");
}
}
In dynamic binding, method is called depending on the type of reference and not the type of object that the reference variable is holding
Here static bindinghappens because method hiding is not a dynamic polymorphism.
If you remove static keyword in front of eat() and make it a non static method then it will show you dynamic polymorphism and not method-hiding.
i found the below link to support my answer:
https://youtu.be/tNgZpn7AeP0
In the case of the static binding type of object determined at the compile-time whereas in
the dynamic binding type of the object is determined at the runtime.
class Dainamic{
void run2(){
System.out.println("dainamic_binding");
}
}
public class StaticDainamicBinding extends Dainamic {
void run(){
System.out.println("static_binding");
}
#Override
void run2() {
super.run2();
}
public static void main(String[] args) {
StaticDainamicBinding st_vs_dai = new StaticDainamicBinding();
st_vs_dai.run();
st_vs_dai.run2();
}
}
Because the compiler knows the binding at compile time. If you invoke a method on an interface, for example, then the compiler can't know and the binding is resolved at runtime because the actual object having a method invoked on it could possible be one of several. Therefore that is runtime or dynamic binding.
Your invocation is bound to the Animal class at compile time because you've specified the type. If you passed that variable into another method somewhere else, noone would know (apart from you because you wrote it) what actual class it would be. The only clue is the declared type of Animal.

What is significance of the term " hiding " in the method hiding concept in java? [duplicate]

This question already has answers here:
What is method hiding in Java? Even the JavaDoc explanation is confusing
(8 answers)
When is method hiding practically used?
(5 answers)
Closed 4 years ago.
The question has been put up to discuss around the term hiding which is associated with static methods in java.
Whenever a static method with the same signature is defined in the parent and the child class, the child class method is said to have hidden the method in the parent class. My question is around the usage of hiding, as we know static methods would be accessed by the class name or if we try to create a reference (which is a bad practice), method would be called based on the reference type. So how does hiding comes into picture, take example of below code:
public class Animal {
public static void testClassMethod() {
System.out.println("The static method in Animal");
}
}
public class Cat extends Animal {
public static void testClassMethod() {
System.out.println("The static method in Cat");
}
public static void main(String[] args) {
Cat myCat = new Cat();
Animal myAnimal = myCat;
Animal.testClassMethod(); // prints The static method in Animal
}
}
Can someone please explain how child method has hidden the parent method here? (parent method is being called using parent reference, so how does hiding comes into picture)
This demonstrates exactly why it's a bad practice to intend to hide a static method. The method is chosen statically, at compile time, without any consideration for the actual instance type.
I suppose the take home phrase should be "hiding is not overriding... and don't do it", to mean that Java doesn't even look at the object/instance (only looking at the declared type):
Cat myCat = new Cat();
Animal myAnimal = myCat;
Animal.testClassMethod();
myAnimal.testClassMethod(); //bad to do, but you can see it uses the declared "Animal" class
Cat.testClassMethod(); //Uses method in Cat
myCat.testClassMethod(); //Uses method in Cat
((Animal) null).testClassMethod(); //Uses Animal method, doesn't look at instance
((Cat) null).testClassMethod(); //Uses Cat method, doesn't look at instance
Now the interesting part: what if you remove the method from Cat?
All of these invocations will still work, using the Animal method, which means that:
It's a very bad practice to hide static methods
It's equally bad to use class instances to invoke static methods, because in the case of hidden methods, it's easy to be misled...
To answer the question: hiding is illustrated with Cat.testClassMethod() or myCat.testClassMethod(), which invokes the static method based on the declared type. When there's no testClassMethod() in Cat, Java calls the parent's.
How has the child method hidden the parent method here?
As you said, by defining a static method with the identical signature.
How does hiding comes into the picture?
Cat.testClassMethod();
Some may expect the invocation of the parent method here (by analogy with polymorphism). But the idea of hiding by class methods is different:
If a class C declares or inherits a static method m, then m is said to hide any method m', where the signature of m is a subsignature (§8.4.2) of the signature of m', in the superclasses and superinterfaces of C that would otherwise be accessible (§6.6) to code in C.
...
A hidden method can be accessed by using a qualified name or by using a method invocation expression (§15.12) that contains the keyword super or a cast to a superclass type.
...
class Super {
static String greeting() { return "Goodnight"; }
String name() { return "Richard"; }
}
class Sub extends Super {
static String greeting() { return "Hello"; }
String name() { return "Dick"; }
}
class Test {
public static void main(String[] args) {
Super s = new Sub();
System.out.println(s.greeting() + ", " + s.name()); // Goodnight, Dick
}
}
JLS 10 - 8.4.8.2. Hiding (by Class Methods)
This example is perfect to show the difference between overriding and hiding. At the same time, it is a bad practice demonstration - calling static methods on an instance.
I will try to make it clear by providing another example.
Since public static methods are inherited, the following snippet
class Animal {
public static void testClassMethod() {
System.out.println("The static method in Animal");
}
}
class Cat extends Animal {
public static void main(String[] args) {
// Cat: I don't have own method, probably I inherited it from the parent.
// O, yes. I can call it.
Cat.testClassMethod();
}
}
prints
The static method in Animal
Now we're going to add testClassMethod to Cat.
class Animal {
public static void testClassMethod() {
System.out.println("The static method in Animal");
}
}
class Cat extends Animal {
public static void testClassMethod() {
System.out.println("The static method in Cat");
}
public static void main(String[] args) {
// Cat: I have two version of the method: mine and the inherited one.
// The caller specified my class name, so he wanted my version.
// I will call my method hiding the parent method.
Cat.testClassMethod();
// If he wanted Animal's version, he would write
Animal.testClassMethod();
// or (DON'T DO THIS)
((Animal)new Cat()).testClassMethod();
}
}
All final, static and private methods and variables use static binding and are bonded by compiler. Static binding uses Type information for binding (in this case Animal).
So, in your case myAnimal.testClassMethod(); will print the static method in Animal because declared type is Animal.
static methods don't take part in dynamic binding (polymorphism).
static methods aren't overritten, static methods are hidden by the subclass.
someone who calls Cat.testClassMethod() might expect the behaviour of Animal.testClassMethod()
So Cat.testClassMethod() is hiding Animal.testClassMethod()

in which areas method hiding is aplicable in java

Please let me know more about method hiding and what is difference between method overriding and method hiding. Thanks
for e.g.
class Test
{
public static void m1(){}
}
class Test2 extends Test
{
public static void m1(){}
}
Why this thing is known as method hiding but not as method overriding?
Have this in mind:
A static method belongs to the class.
A non-static method belongs to the object.
Now take a look at this code:
public class Test {
public static void main(String[] args) {
Animal d = new Dog();
d.printStatic(); //prints "Animal"
d.print(); //prints "Dog"
}
}
class Animal {
static void printStatic() {
System.out.println("Animal");
}
void print() {
System.out.println("Animal");
}
}
class Dog extends Animal {
static void printStatic() {
System.out.println("Dog");
}
void print() {
System.out.println("Dog");
}
}
The printStatic() method that is static, is hidden by the Dog class. Since static methods belong to the class, and d is declared as an Animal in the line Animal d = new Dog();, the call will refer to the method in the Animal class.
The print() method that is not static, is overriden by the Dog class. Since non-static methods belong to the object, and the d variable is pointing to a Dog, the call will refer to the method in the Dog class.
Only instance methods (so, without the static keyword) can be overridden.
So, if in a subclass, you redeclare the static method of a superclass, you don't override the static method, you declare a new static method with no relation with which of the super class.
So when you invoke the static method, the effective call method depends on which class name is prefixed before the static method invocation.
If you prefix with the super class, it's the static method of the super class which is called.
If you prefix with the subclass, it's the static method of the subclass which is called.
Personally, I find the "hiding" term not very helpful for understanding the concept.

How these static override methods are calling? [duplicate]

Sample 1:
class Animal {
public static void saySomething() { System.out.print(" Gurrr!");
}
}
class Cow extends Animal {
public static void saySomething() {
System.out.print(" Moo!");
}
public static void main(String [] args) {
Animal [] animals = {new Animal(), new Cow()};
for( Animal a : animals) {
a.saySomething();
}
new Cow().saySomething();
}
}
Output is:
Gurrr! Gurrr! Moo!
Sample 2:
class Animal {
public void saySomething() { System.out.print(" Gurrr!");
}
}
class Cow extends Animal {
public void saySomething() {
System.out.print(" Moo!");
}
public static void main(String [] args) {
Animal [] animals = {new Animal(), new Cow()};
for( Animal a : animals) {
a.saySomething();
}
new Cow().saySomething();
}
}
Output:
Gurrr! Moo! Moo!
I just don't understand why making saySomething non-static causes the second call to saySomething invoke the Cow version instead of the Animal version. My understanding was that Gurrr! Moo! Moo! would be the output in either case.
When you call saySomething() on an animal, the actual type of the animal doesn't count because saySomething() is static.
Animal cow = new Cow();
cow.saySomething();
is the same as
Animal.saySomething();
A JLS example :
When a target reference is computed and then discarded because the invocation mode is static, the reference is not examined to see whether it is null:
class Test {
static void mountain() {
System.out.println("Monadnock");
}
static Test favorite(){
System.out.print("Mount ");
return null;
}
public static void main(String[] args) {
favorite().mountain();
}
}
which prints:
Mount Monadnock
Here favorite returns null, yet no NullPointerException is thrown.
Resources :
JLS - Is the Chosen Method Appropriate?
On the same topic :
Java Static confusion
You cannot override static methods with the same signature in subclasses, just hide them.
For class methods, the runtime system invokes the method defined in the compile-time type of the reference on which the method is called. For instance methods, the runtime system invokes the method defined in the runtime type of the reference on which the method is called.
http://life.csu.edu.au/java-tut/java/javaOO/override.html
Some of the known Overriding "PITFALLS"
static methods cannot be overridden
private methods cannot be overridden
This explains the output.
static methods are bound to their class at compile time and cannot be used polymorphically. When you declare a "static" method on Animal, it is forever bound to the Animal class and cannot be overridden. Static methods are bound to the Class object, not an instance of the Class.
Regular methods are bound at runtime and so the JVM can look at your call to "saySomething" and attempt to determine if you're passing around a subclass of Animal and if so, has it overridden the saySomething() method. Regular methods are bound to an instance of an object, not to the Class itself.
This is also why you could never do this:
class Animal
{
public abstract static void saySomething();
}
Since "static" means "bound at compile time", it never makes sense for something to be static and abstract.
Static methods are tied to the "Class", not the "Instance" of the object.
Since you are referring to an "Animal" and calling the static method saySomething(). It will always make the call to "Animal" unless you are referring to a Cow.

Is this still polymorphism?

While coding, I got an interesting doubt about polymorphism and I couldn't understand a solution for this.
public class Animal {
public void getLegs() {
SOP("4 legs");
}
}
public class Kangaroo extends Animal {
public void getLegs() {
SOP("2 legs");
}
public static void main(String[] args) {
Animal a = new Kangaroo(); // without changing this how can I get Animal getLegs
SOP(a.getLegs()); // Important Line
}
}
Now If I want to call the getLegs method of Animal, how do I? Is it possible? Is it still polymorphism?
Yes, it is the most basic form of demonstrating polymorphisim.
Basically you are dealing with an Animal named a. When you call a.getLegs() your code doesn't bind to the implementation of getLegs() in Animal, rather it binds to the lowest sub-class implementation, getLegs() in Kangraoo().
If the Animal has an implementation, it is said to be hidden by the subclass implementation. If Animal has no implementation, then it is not possible to construct stand-alone classes of Animal as they lack implementations for all of the required methods, and under such a circumstance, Animal is said to be an abstract class (one that cannot be constructed directly, but only can be constructed by it's sub classes).
If you really want to call your method for Animal, and you can employ a static method, you can use hiding instead of overriding.
It works as follows: for static methods only, the called method is the one related to the declared type, not the object instance. In other words, it follows the class because the method is a class method, not an instance method.
An example, adapted from this page:
public class Animal {
public static void testClassMethod() {
System.out.println("The class" + " method in Animal.");
}
public void testInstanceMethod() {
System.out.println("The instance " + " method in Animal.");
}
}
public class Kangaroo extends Animal {
public static void testClassMethod() {
System.out.println("The class method" + " in Kangaroo.");
}
public void testInstanceMethod() {
System.out.println("The instance method" + " in Kangaroo.");
}
public static void main(String[] args) {
Kangaroo myRoo = new Kangaroo();
Animal myAnimal = myRoo;
myRoo.testInstanceMethod();
myAnimal.testInstanceMethod();
Kangaroo.testClassMethod();
Animal.testClassMethod();
}
}
The result will be (pay attention to the 3rd and 4th lines, as opposed to the 1st and 2nd):
The instance method in Kangaroo.
The instance method in Kangaroo.
The class method in Kangaroo.
The class method in Animal.
In Java it's not possible to access Animal's implementation. It will always return Kangaroo's version.
(Note in C# it is possible by tagging the overriding method with "new", but it's a fairly specialised use case).
Accessing what appears to be an Animal but getting the behaviour specified by Kangaroo is exactly what polymorphism is - the ability for a child object to be substituted wherever its parent is expected.
In general you wouldn't want to have the calling code know about the inheritance hierarchy because this would tightly couple your code together. If you genuinely need to access Animal's implementation of this method it suggests your design is probably wrong.
The spirit of Polymorphism is to execute different code decided at runtime. To make it more clear, I'll modify your code a bit.
public class Animal {
public void getLegs(){
SOP('4 legs');
}
}
public class Kangaroo extends Animal{
public void getLegs(){
SOP('2 legs');
}
public static void main(String[] args){
Animal a = new Kangaroo(); //without changing this how can I get Animal getLegs
Kangaroo kng= new Kangaroo ();
Animal an = new Animal();
SOP(a.getLegs()); // Kangaroo's version is called
SOP(kng.getLegs()); //Again, Kangaroo's version is called
SOP(an.getLegs()); //Animal version is called
}
}
and Yes, as all say you can't call Animal from your line Animal a = new Kangaroo();..as none will want to do it. Rather he will directly write. Animal a = new Animal();..
So finally it is the object not referance which decides which method will be called
Now If I want to call the getLegs method of Animal, how do I? Is it possible?
If you want to access the overridden method - which contradicts polymorphism - you can use reflection. Get the getLegs method from Animal's class, and then invoke it on your Kangaroo object. However, this is a hack, and not something you'd do in a regular program.
SOP( Animal.class.getMethod("getLegs").invoke(a) );

Categories

Resources