Reputation: 10543
class Test {
public static void main(String[] args) {
Animal a = new Dog();
Dog d = new Dog();
d.makeNoise(); // output "Sub"
a.makeNoise(); // output "Sub" then what is use of calling this. why not call d.makeNoise() only.
}
}
abstract class Animal {
public void makeNoise() {
System.out.println("Super");
}
}
class Dog extends Animal {
@Override
public void makeNoise() {
System.out.println("Sub");
}
}
We had 15 minutes discussion over this topic(15 minutes is too long I guess) I explained interviewer about how dynamic polymorphism will be achieved with the help of a.makeNoise();
but still she was saying both are giving same output.
a.makeNoise();
output "Sub" then what is use of calling this. why not call d.makeNoise() only
I went to interface also but still question was if subclass reference is giving same output then why to use superclass reference.
Interviewer question was, what difference
a.makeNoise();
makes? why not calld.makeNoise();
only when both are giving same output?
What could be the possible correct answer?
Upvotes: 0
Views: 997
Reputation: 9
consider there are 3 classes
class Test {
public static void main(String[] args) {
Animal a = new Animal();
int user_input=userinput(); //returns 1 for cat and 2for dog
switch(user_input)
{
case 1:Animal d=new Cat();
break;
case 2: Animal d=new Dog();
break;
}
d.makeNoise(); // output "Bark"/"meow" as per user input(dynamic linking)
a.makeNoise(); // output "Squawk" - a is an animal that squawks
}
}
class Animal {
public void makeNoise() {
System.out.println("Squawk");
}
}
class Cat extends Animal {
@Override
public void makeNoise() {
System.out.println("meow");
}
}
class Dog extends Animal {
@Override
public void makeNoise() {
System.out.println("Bark");
}
}
Upvotes: 1
Reputation: 1300
Animal a = new Dog();
a is a a reference of type Animal but it refers to the object of type Dog.
Here Dog overrides makeNoise() method of Animal class.
class Animal {
public void makeNoise() {
System.out.println("Squawk");
}
}
class Dog extends Animal {
@Override
public void makeNoise() {
System.out.println("Bark");
}
}
Since object is of Dog class JVM will bind Dog class' makeNoise() method to the object and binding will be done at runtime.
so the Output of
a.makeNoise();
will be
sub
Upvotes: 0
Reputation: 11
i will give one general ex:- personA has one bank account he has all permissions on that account(withdraw,deposit,loanetc). personB wants to deposit money into personA account in this time he wants to access personA's account but we have to provide deposit permissions only.
class perosnB
{
public void deposit()
{
................
}
}
class personA extends personB
{
public void deposit()
{
......
}
public void withdraw()
{
......
}
}
personA p=new personB();
PersonB p2=new personB();
by using p object we can access only withdraw method. by using p2 we can access deposit also. weather personA class is abstract or not. if personA is abstract class creating object for personA class is not possible( personA p=new personA()) . personA p=new personB() is possible.
Upvotes: 0
Reputation: 997
class Account {
public static void main(String[] args) {
Animal a = new Dog();
Dog d = new Dog();
d.makeNoise();
a.makeNoise();
a = new Cat();
a.makeNoise();
}
}
abstract class Animal {
public void makeNoise() {
System.out.println("Super");
}
}
class Dog extends Animal {
public void makeNoise() {
System.out.println("Sub");
}
}
class Cat extends Animal {
}
See the above modified example and the observations
Upvotes: 0
Reputation: 1963
Your simplified example does not present the case well enough.
Collection<Animal> caged = getCagedAnimals();
for (Animal a : caged)
a.makeNoise();
As there are many types of animals (classes), each makes a different noise. We do not need any typecasting to obtain different behavior, so to say. Imagine the horrors which would happen if we would want each animal to make a noise without polymorphism:
for (Animal a : caged) {
if (a instanceof Dog)
((Dog)a).woof(); // or, ((Dog)a).makeNoise()
else if (a instanceof Cat)
((Cat)a).meow(); // or, ((Cat)a).makeNoise()
else {...}
}
Let us have an object of type T. We are trying to invoke toString() (defined by Object class) Dynamic method invocation proceeds as follows (actually, a virtual method table is used):
C = T
do
if (C defines toString()) {
call T.toString()
break
}
C = superclass of C
while (C != null)
throw new NoSuchMethodError();
Now, if we have
Object obj = new T();
and we call
obj.toString();
we are actually calling toString() of class T.
Upvotes: 1
Reputation: 33273
The example below illustrates dynamic polymorphism. Both a and d are declared to be Animals, but d is actually a dog.
Notice that when I call makeNoise on the Animal d, java will know that d is actually a dog and not just any animal.
class Test {
public static void main(String[] args) {
Animal a = new Animal();
Animal d = new Dog();
d.makeNoise(); // output "Bark" - d is an animal that barks
a.makeNoise(); // output "Squawk" - a is an animal that squawks
}
}
class Animal {
public void makeNoise() {
System.out.println("Squawk");
}
}
class Dog extends Animal {
@Override
public void makeNoise() {
System.out.println("Bark");
}
}
Upvotes: 2
Reputation: 48807
Animal a = new Dog(); // this animal is a dog
Dog d = new Dog(); // this dog is a dog
A dog is a dog, however you declared it.
a.getClass()
equals d.getClass()
equals Dog.class
.
On the other hand:
Animal a = new Animal(); // this animal is an animal
a.makeNoise(); // prints "Super"
Upvotes: 2
Reputation: 4202
This is the reason-
Animal a = new Dog();
Animal is dog so noise would be same :)
If create another animal, say Cat, with that method, and point animal to Cat, you should get a different noise.
Upvotes: 1