Полиморфизм и наследование - PullRequest
2 голосов
/ 23 октября 2011

У меня есть эти классы:

class A
 {
    public int Foo()
    {
        return 5;
    }
}

class B : A
{
    public int Foo() 
    {
        return 1; 
    }
}

, и я использую их следующим образом:

        B b = new B();
        int x = b.Foo();

и хотя Foo () в базовом классе не является виртуальным или впроизводный класс - у него нет ключевого слова override, все равно x равно 1. Тогда, как используются виртуальные и override ключевые слова?

Ответы [ 5 ]

4 голосов
/ 23 октября 2011

Полиморфизм позволяет рассматривать тип B как тип A.

A b = new B();
int x = b.Foo(); // x will be 1 if virtual, 5 if not.
3 голосов
/ 23 октября 2011

Предполагая, что это C #:

Вы не переопределили Foo.Вы скрыли Foo базового класса.Это означает, что если вы вызовете foo переменную со статическим типом B, вы получите B.Foo(), а вызов статического типа A (даже если во время выполнения тип B) даст вам A.Foo().

Ваш код должен выдавать предупреждение компилятора, поскольку вы скрываете базовый метод без использования ключевого слова new.

B b = new B();
int x = b.Foo();//calls B.Foo
A a = b;//Runtime type B, compiletime type A
a.Foo(); // calls A.Foo

Если вы переопределили Foo, тогда вы 'd B.Foo() в обоих случаях.

1 голос
/ 23 октября 2011

Ваш тип объявления - B, поэтому вы будете вызывать реализацию B .. если ваш тип объявления - A и вы создаете экземпляр нового экземпляра B, то вы получаете 5 в качестве декларирующего типа, если только вы не используете виртуальное ключевое слово для поддержки полиморфизма.

1 голос
/ 23 октября 2011

Маркировка метода как virtual позволяет ему быть полиморфным . Это означает, что он может быть переопределен в производных классах. Полиморфный метод вступает в игру, когда вы вызываете его из базового класса reference . Метод, который будет вызываться во время выполнения, зависит от класса времени выполнения объекта, на который указывает ссылка на базовый класс. Если его тип времени выполнения является самим базовым классом, то вызываемый метод будет тот же, что и в базовом классе; если тип среды выполнения имеет производный тип, который переопределил этот метод, то вызываемый метод будет переопределенным методом.

Если метод не virtual, он будет обязан вызывать метод, который объявлен в типе ссылки времени компиляции на объект, независимо от его типа во время выполнения.

0 голосов
/ 23 октября 2011

Смысл сделать метод виртуальным - это когда вы вызываете метод через указатель или ссылку на базовый класс:

A p = new B();<br> int x = p.Foo();

В этом примере статический тип p равен A, а динамический тип - B. Это означает, что из-за полиморфизма вызывается B.Foo, хотя статический тип - A.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...