Jon McKee
Ответ Гриффа точен но вот еще один код:
class A
{
public void output() { System.out.println("Called A."); }
}
class B extends A
{
/* Override isn't required. It's just for clarity purposes and depending on
* your dev software it might give you a warning if you override something
* without specifying @Override just in case you've done it accidentally.
*/
@Override
public void output() { System.out.println("Called B."); }
public void somethingSpecificToB() { System.out.println("B only."); }
}
class C extends A
{
public void somethingSpecificToC() { System.out.println("C only."); }
}
class Test
{
public static void main(String[] args)
{
polymorphicParam(new A());
polymorphicParam(new B());
polymorphicParam(new C());
A value = polymorphicReturn(true); //Return value is actually type 'A'
value.output();
value = polymorphicReturn(false); //Return value is actually type 'B'
//Can only call output(), since we're treating what was returned as
//an instance of class A
value.output();
}
private static void polymorphicParam(A param)
{
//Even if the actual input class is B or C, you can still only
//use the members defined in class A since that's what the parameter
//type is.
param.output();
}
private static A polymorphicReturn(bool createA)
{
if (createA)
return new A();
return new B();
}
}
//Output:
// Called A.
// Called B.
// Called A.
// Called A.
// Called B.
Таким образом, здесь классы B и C все еще могут удовлетворять вызовам
output()
таким образом, поэтому может быть "приведено вверх" и обработано как экземпляры класса A. класс B использует свою собственную реализацию
output()
в то время как класс C наследует реализацию класса A.
Фактически, поскольку Java вынуждает либо переопределять, либо наследовать открытые члены от суперклассов, этот полиморфизм подтипов всегда работает. Java не позволит вам сломать его, например, изменив
output()
к
private
в подклассе.