问题
public class A {
protected int x = 10;
A() {
System.out.println("Constructor A" ) ;
}
public void test() {
System.out.println(" A " );
}
public void Aex() {
System.out.println(" Aex " ) ;
}
public void testg() {
System.out.println("Hello");
}
}
public class B extends A {
B() {
System.out.println("Constructor B" ) ;
}
B(int num){
this.x = num ;
//System.out.println(this.x);
}
public void test() {
System.out.println(" B " );
}
public int getx() {
return this.x;
}
}
public class C {
public static void main( String [] args ) {
A a = new B();
//a.test();
a.Aex();
//a.testg();
B b = new B(5);
a = b;
a.test();
System.out.println( a.getx() ) ;
}
}
Class B
inherits from class A
and both have a method called test()
. I can create a base class reference to a derived class object , so I create a reference A a = new B();
. When I call a.test()
, the test()
method of B
is called which I understand , which helps me to prevent conditional statements in my code. But suppose B
has another method called void getx()
, and I want to call that method, I cannot call it with a base class reference , since the base class has no method called void getx()
. So how is polymorphism useful in such a situation ? The only way to call getx
is to create a reference of derived class and call getx()
.
回答1:
Rather than classes A
and B
let's use classes Animal
and Bird
for an example.
Say your Animal
class has methods eat
and sleep
(things that all animals do) and your Bird class also has a fly
method (which only birds can do). If you have a reference to an Animal
object it would make no sense to be able to call the fly
method on this variable because you don't know what kind of animal it is, it could be a Slug
or an Wombat
.
回答2:
The whole point is not to be aware of the existence of getx()
method and not to call it with a reference to A
.
If you really have to call it, you can cast it to the desired type:
B b = (B) a;
b.getx();
But in that case, you should reconsider your design and either change the design to avoid casting, or use a reference to B
in the first place.
Imagine that you are inviting friends to a dinner. At this level of abstraction, you would just tell them to come:
for (Friend friend : friends) {
friend.comeToDinner();
}
You would not tell them to exit their home, sit into the car, drive it, stop on red traffic light, continue driving on green light... stop at your home, exit the car. You tell them what to do, not how to do it (some will come by car, some by public transportation, etc).
Each Friend
instance will use its own state and implementation to execute the comeToDinner
method.
回答3:
What you call a deficiency is actually the key advantage of polymorphism: you can reach the subclass's overriding method without knowing anything about it or its own methods. That's what the phrase "programming against the interface" is meant to capture.
回答4:
It seems you are missing an important piece of OO magic: the method getx() can be declared as abstract in A and you will not have to implement it there. This will allow you to call it on the base class (which will become abstract itself) and at the same time you don't need to have an implementation of the method there.
回答5:
You already stated how it could be useful, you can call methods on a reference to base class which may actually have a value of an inherited class, this makes your code extensible.
and I want to call that method, I cannot call it with a base class reference , since the base class has no method called void getx() .
This is a contradiction, why do you want to call a method of a class that does not exist?
codebox has an excellent example in his answer of why it doesn't make sense to call the non-implemented method.
来源:https://stackoverflow.com/questions/32272958/how-is-dynamic-polymorphism-useful-when-i-cant-call-derived-class-methods-with-b