Абстрактный класс в левой части объекта в C # - PullRequest
0 голосов
/ 25 сентября 2018

У меня есть два вопроса относительно использования абстрактного класса в левой части экземпляра объекта.

AbstractClass MyClass = new ConcreteClass();

1 - Как это называется? (когда вы объявляете абстрактный классслева.)

например,

Car MyNiceCar = new NiceCar();

Я знаю, что это относится к полиморфизму, но я специально спрашиваю, как описать / выразить в словах сценарий при объявлении абстрактного класса слева.

2 - А зачем это делать? т.е. зачем вам это делать:

Car MyNiceCar = new NiceCar();

А не:

NiceCar MyNiceCar = new NiceCar();

?

Может быть, ответ на вопрос 2 будет таким, чтобы я мог сделать следующее?

Car MyNiceCar = new NiceCar();

.
. //do some logic to decide if I can have a nicer car.
.

MyNiceCar = new EvenNicerCar();

Ответы [ 3 ]

0 голосов
/ 25 сентября 2018

1 - Как это называется?

Это тип полиморфизма, который называется «полиморфизм включения».Это позволяет вам создавать ограничения на тип переменной, которая может использоваться в вашем коде, но при этом обеспечивает некоторую гибкость типов.Java и C #, например, имеют обобщенные типы, которые позволяют различным типам и ссылкам использовать один и тот же код.Однако они часто сталкиваются с проблемами во время выполнения, которые в противном случае могли бы быть обнаружены статическим анализатором кода.Обычно считается менее рискованным полагаться на статический анализатор (при условии, что ваша IDE имеет хороший), чем ждать и обнаруживать, что в вашем коде есть ошибки после вашего выпуска.

2 - ИПочему это так?

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

Рассмотрим следующее:

// Both classes contain an Accelerate() function
NiceCar MyNiceCar = new NiceCar();
EvenNicerCar MyEvenNicerCar = new EvenNicerCar();

// We're forced to use these methods separately
MyNiceCar.Accelerate();
MyEvenNicerCar.Accelerate();

////////////////////////////////////////////////////////////////////////////////////////////////////

// We can make this code much smaller and less prone to copy/paste errors using polymorphism!
Car[] MyPolymorphicArray = new Car[] { new NiceCar(), new EvenNicerCar() };
foreach(c in MyPolymorphicArray) { c.Accelerate(); }

Используя этот тип синтаксиса, вы можете видеть, что я могу сделать код меньше, более управляемым, безопасным по типу, и наш статический анализатор кода будет жаловаться, если мы ошибемся, вместо того, чтобы ждать до времени выполнениявыяснить.При использовании этого типа архитектуры убедитесь, что методы, предназначенные для использования экземплярами, должны находиться либо в интерфейсе, либо в родительском классе этого объекта, чтобы избежать ошибок реализации.Кроме того, обратите внимание, что если вы сделаете это, метод Accelerate () может потребоваться записать только в родительском классе, что поможет сделать код еще меньше.

0 голосов
/ 27 сентября 2018

Исходя из двух превосходных ответов @Mars и @ chris-mauer, которые оба отлично ответили на вопрос 2 моего поста.И позволил мне изучить эту концепцию дальше.

Я хочу включить ответ на Вопрос 1 моего поста следующим образом.Я спросил:

AbstractClass MyClass = new ConcreteClass();

1 - Как это называется? (когда вы объявляете абстрактный класс слева.)

Из статьи ниже, я полагаюправильный ответ:

Upcasting

Более подробно об общей концепции, которой является Полиморфизм включения, я изучил следующую статью: http://www.msdotnet.co.in/2014/05/how-to-implement-polymorphism-concepts.html

0 голосов
/ 25 сентября 2018

1) Вы создаете ссылку на базовый класс для своего производного класса.
Редактировать:
Другие слова для BaseClass: SuperClass, ParentClass
Другие слова для DerivedClass: SubClass, ChildClass Не спрашивайте, почемуЕсть так много слов для каждого.Это что-то вроде типа Spaces vs Tabs.

2) Вы делаете это так, что вы можете использовать virtual функций / свойств, которые, как вы знаете, будут у всех производных классов.Вы хотите сделать что-то, что может сделать автомобиль, и вам все равно, если это CrapCar, NiceCar или SuperNiceCar

Car car = new MyNiceCar();
car.honk(); //meep!
car = new SuperNiceCar();
car.honk(); //beep beep!

Однако вы не можете пойти другим путемоколо.

SuperNiceCar может поддерживать UseTurbo(), но MyNiceCar - нет.

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

Смотрите также

...