Работает очень хорошо если вы понимаете это .
Существует также 2 варианта полиморфизма. Первое очень легко понять в java-esque:
interface A{
int foo();
}
final class B implements A{
int foo(){ print("B"); }
}
final class C implements A{
int foo(){ print("C"); }
}
B и C имеют общий интерфейс. В этом случае B и C не могут быть расширены, поэтому вы всегда уверены, какой метод foo () вы вызываете. То же самое касается C ++, просто сделайте A :: foo чистым виртуальным.
Во-вторых, хитрее полиморфизм во время выполнения. В псевдокоде это выглядит не так уж плохо.
class A{
int foo(){print("A");}
}
class B extends A{
int foo(){print("B");}
}
class C extends B{
int foo(){print("C");}
}
...
class Z extends Y{
int foo(){print("Z");
}
main(){
F* f = new Z();
A* a = f;
a->foo();
f->foo();
}
Но это намного сложнее. Особенно, если вы работаете в C ++, где некоторые из объявлений foo могут быть виртуальными, а часть наследования может быть виртуальной. Также ответ на этот вопрос:
A* a = new Z;
A a2 = *a;
a->foo();
a2.foo();
может не соответствовать вашим ожиданиям.
Просто внимательно следите за тем, что вы делаете, и не знаете, используете ли вы полиморфизм во время выполнения. Не будьте слишком самоуверенными, и если вы не уверены, что что-то собирается делать во время выполнения, протестируйте это.