в C # Уп, как объяснить, почему базовый класс может взять экземпляр производного класса - PullRequest
1 голос
/ 02 марта 2012

Ну, так как я набираю это с мобильного, я не могу набрать или скопировать весь код, поэтому я ссылаюсь на сообщение SO -> В чем ошибка в этом коде? Интервью

Если вы делаете X a = новый Y (); это компилируется. Интервьюер спросил, как это возможно? Я знаю, что это будет возможно, если X был определен как абстрактный класс, но это также не так.

Ответы [ 5 ]

4 голосов
/ 02 марта 2012

Если Y наследует X, тогда Y равен своего рода X и может использоваться везде, где может X.

Это сработает независимо от того, является ли X абстрактным.

1 голос
/ 02 марта 2012

Чтобы расширить ответ Бранко Димитриевича, это возможно из-за принципа замены Лискова .

В своем комментарии вы сказали

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

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

object o = anything;
Console.WriteLine(o.ToString());
Console.WriteLine(o.GetHashCode());
Console.WriteLine(o.GetType().Name);

Вы можете сделать это, потому что у каждого объекта есть методы ToString, GetHashCode и GetType , потому что тип времени выполнения каждого объекта наследует прямо или косвенно от объекта.

Вы можете сделать то же самое с базовым классом, отличным от object:

class X
{
    public string Exclamation { get { return "Inherit this!"; } }
}
class Y : X
{
    public string Question { get { return "What's up with that?"; } }
}

Тогда совершенно законно сказать

X x = new Y();
Console.WriteLine(x.Exclamation);

Но, конечно, вы не можете сказать

X x = new Y();
Console.WriteLine(x.Question);  //does not compile!

Чтобы использовать свойство Question, вам нужно иметь ссылку типа Y.

Напомним: поскольку каждый член базового класса также является членом производного класса, вы можете использовать экземпляр производного класса, как если бы он был экземпляром базового класса. Экземпляр производного класса содержит все члены базового класса.

Вы подняли тему абстрактных классов. Конечно, абстрактный класс не может быть создан; Вы можете создать экземпляр класса, производного от абстрактного класса. Однако это не влияет на принцип подстановки, за исключением того, что переменная, тип которой является абстрактным классом , должна ссылаться на экземпляр производного типа, тогда как переменная, тип которой не является абстрактным ( unsealed) класс может ссылаться на экземпляр производного типа.

1 голос
/ 02 марта 2012

класс Y либо наследует класс X, либо X является интерфейсом, который наследует Y.

Но если бы кто-то спросил меня об этом на собеседовании, я бы сказал, что не хочу работать где-либоразработчики создают типы с именами из одного символа.

0 голосов
/ 02 марта 2012

Допустим,

class Animal
{

}

class Tiger:Animal
{

}

Animal fooAnimal = new Tiger()

Это возможно, поскольку Tiger является типом Animal.

0 голосов
/ 02 марта 2012

C # поддерживает то, что называется ковариацией и контравариантностью.Ковариантность - это способность неявно (без какого-либо дополнительного кода) преобразовывать производный класс, в данном случае Y, в базовый класс, в данном случае X. Это возможно, потому что Y расширяет X, то есть Y имеет все те же члены, что и XЭто позволяет назначать переменную типа X производному классу.

Это важно для расширения классов и перегрузки.Если класс X содержит метод с именем Foo, а производный класс X создает метод с именем Foo, метод из Y будет вызываться, даже если он приведен к типу X. Вот пример:

public class X
{
    public void Foo()
    {
         Console.WriteLine("Something");
    }
}
public class Y : X // y derives from X
{
    public override void Foo()
    {
         Console.WriteLine("Class Y");
    }
}
public class Program
{
    static void Main()
    {
          X item = new Y(); // covariance.
          item.Foo();   // prints "Class Y"
    }
}

Я надеюсь, что это не снисходительно, я не знаю ваш уровень квалификации.Эта статья из MSDN объясняет это буквально, http://msdn.microsoft.com/en-us/library/ee207183.aspx.

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