Наследование инициализированных полей - PullRequest
1 голос
/ 07 октября 2019

В C # есть поведение, которого я действительно не понимаю:

class Animal {
        public string species = "animal";

        public void Introduce() {
            Console.WriteLine(species);
        }
    }


    class Cat: Animal {
        new public string species = "cat";

        // public void Introduce() {Console.WriteLine(species);}
    }

    class Program
    {
        static void Main(string[] args)
        {
            var cat = new Cat();
            cat.Introduce();
        }
    }

Этот фрагмент кода при выполнении выдает >>> animal.
Для меня, поскольку Cat наследует Animal, вызывая cat.Introduce должен вызывать Animal.Introduce "в области действия экземпляра cat". т.е. Я не понимаю, почему программа выбирает поле species для Animal, а не поле Cat ...

Я знаю, что могу использовать обходные пути, но я верю, что я 'Мне не хватает некоторого смысла в дизайне c #, кто-то может объяснить это поведение?

Спасибо

1 Ответ

10 голосов
/ 07 октября 2019

Я не понимаю, почему программа выбирает поле видов Animal, а не поле Cat ...

Поскольку модификатор new скрывает унаследованное speciesчлен ... но только внутри Cat экземпляра . Вы вызываете метод базового класса, который знает только своего собственного члена species.

Если вы даете своему Cat классу метод IntroduceCat(), где вы печатаете его species и вызываете его,вы увидите печатную строку "cat".

Если вы хотите переопределить член в производном классе, вы должны пометить элемент как virtual в базовом классе и override впроизводный класс. Но вы не можете сделать это с полями, поэтому вам придется сделать это свойством.

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

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