C # наследство (начинающий) - PullRequest
0 голосов
/ 18 ноября 2010

У меня есть кое-что, на что должно быть легко ответить для большинства из вас, я думаю:

У меня есть следующие классы:

class One
{
string first;
}
class Two : One
{
string second;
}

Теперь я хотел заменить все значения One вДва значения.Поэтому я попробовал следующее:

One one = new One();
Two two = new Two();
two = (Two) one; // <= this seems to not work

Итак, действительно ли мне нужно реализовать метод, который копирует все элементы от одного до двух?

Ответы [ 5 ]

2 голосов
/ 18 ноября 2010

One не наследуется от Two, и это то, что не работает замечательно.

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

Например:

public class Cat {
}

public class Dog {
}

Что общего у этих двух?

  1. У них четыреноги;
  2. Все они животные;
  3. У них есть волосы;

Что у них общего?

  1. Aкошка мяукает;
  2. собака лает;

Давайте пересмотрим нашу модель, установив ее в следующем порядке.

public class Cat {
    public bool HasHair { get { return true; } }
    public int Legs { get { return 4; } }
    public string Speaks { get { return "Meows"; } }
}

public class Dog { 
    public bool HasHair { get {return true; } }
    public int Legs { get { return 4; } }
    public string Speaks { get { return "Barkles"; } }
}

Теперь, чтобы сэкономить время и кодирование,что мы могли сделать?Обобщите, что общего у обоих классов?Хорошо!Но как сделать так!?

public class Animal {
    public bool HasHair { get { return true; } }
    public int Legs { get { return 4; } }
    public virtual string Speaks { get { return "Does a sound"; } }        
}

// We can now inherit from Animal to write our Cat and Dog classes.
public class Cat : Animal {
    public overrides string Speaks { get { return "Meows"; } }
}

public class Dog : Animal { 
    public overrides string Speaks { get { return "Barkles"; } }
}

И вы можете сделать:

Dog dog = new Dog();
dog.Legs; // Because Legs is an Animal property, and a Dog inherits from Animal, then Dog has a property called Legs, since it got it from his base class.

Теперь мы можем сделать:

Animal pet = (Animal)(new Cat());

Тем не менее, выможно ввести Cat к Animal, потому что равно Animal!Теперь вы должны учесть, что ваш tytypeasted Cat будет "издавать звук", а не "мяуканье", так как при наборе типов от Cat до Animal вы говорите, что хотите работать с любым AnimalДо тех пор, пока он один.Так что и Cat, и Dog являются животными.

Мы могли бы продвинуть наш пример еще дальше, сказав, что не у каждого животного есть четыре ноги, у некоторых их нет, а у других только две.Тогда мы должны были бы обобщить и специализировать соответственно.

1 голос
/ 18 ноября 2010

Короче говоря: Да

Как и то, что уже было сказано, Один не наследуется от Два, поэтому здесь нет «логического» действия по умолчанию.Вы должны посмотреть на Операторы преобразования .Это позволит вам по-прежнему использовать синтаксис two = (Two) one после определения оператора, например так (в классе def):

public static explicit operator Two(One o)
    {
        var t=new Two();
        t.first=o.first;
        t.second="default";//or whatever kind of default value you want
        return t;
    }
0 голосов
/ 18 ноября 2010

Важно помнить, что один и два являются просто указателями в памяти на экземпляр объекта.

Если бы мы написали это на простом английском, это выглядело бы примерно так:

One one = new One();

Создать указатель в памяти, который ссылается к объекту типа One и пометить его one , затем создайте объект типа One и поместите его в ячейку памяти обозначено один .

two = (Two) one;

Заменить объект, на который ссылается two с объектом, на который ссылается one , и относиться к нему как к объекту типа Two

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

0 голосов
/ 18 ноября 2010

Да, вы должны реализовать метод, который копирует всех членов one в two. Обычно вы бы сделали конструктор:

public Two(One one) {
    this.first = one.first;
}

// Elsewhere ...
Two two = new Two(one);

Или, если вы хотите скопировать поверх значений существующего экземпляра, вы можете сделать это с помощью метода экземпляра:

public void CopyValuesFrom(One one) {
    this.first = one.first;
}

// Elsewhere ...
Two two = new Two();
two.CopyValuesFrom(one);
0 голосов
/ 18 ноября 2010

Вы не можете разыграть One как Two, потому что One не наследуется от Two. И наоборот, все будет работать нормально (Two two = new One();)

Чтобы получить Two из One, вам нужно будет создать новый Two. У вас может быть метод, который копирует все элементы One в Two, или вы можете иметь конструктор для Two, который принимает One и устанавливает свойства оттуда.

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