2013-08-07 2 views
0

Я знаком с абстрактными классами, интерфейсами и т. П.Зачем определять абстрактные классы C# без абстрактных членов

Что мне непонятно, почему кто-нибудь создаст абстрактный класс C#, у которого нет абстрактных элементов? (компилятор C# позволяет это).

Пример:

public abstract class House 
{ 
    public void OpenDoor() 
    { 
     Console.WriteLine("Door opens"); 
    } 
} 
+2

Я думаю, что в компиляторе потребуется больше кода, чтобы определить эту проблему и предотвратить ее , Таким образом, вопрос может быть отменен - ​​почему компилятор должен быть специально разработан для предотвращения этого? –

+0

Действительно действительный вопрос. И, на мой взгляд, это признак плохого дизайна. Обычно я делал это в своем прошлом, и в конце концов мне нужно отметить 'OpenDoor' как виртуальную, потому что мои производные дома нуждаются в конкретном методе для этого. Один из вариантов заключается в том, чтобы добавить еще один метод «OnOpenDoor», который является виртуальным защищенным, что позволяет детям иметь определенную реализацию, контролируя «абсолютную» реализацию из базового класса. – Fendy

ответ

0

Обобщение

Абстрактные классы могут быть концептуальный 'Интерфейс'. Это отличается от интерфейса .NET. Обобщенный пример интерфейса:

// List that accepts the conceptual interface 
List<Car> cars = new List<Car>(); 

// Specialized instance that will be added to the list 
Car myCar = new Toyota(); 
cars.Add(myCar); 

Наследование

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

Использование

Dhananjay написал хороший пост об использовании. Он утверждает, что абстрактные классы используются для моделирования иерархии классов. Однако интерфейсы используются для связи. То, что объект на самом деле не имеет значения.

+0

Скажите, что я хочу иметь класс с именем 'Fishman'. Наследуется ли она от 'Fish', или она унаследована от« Mammal »? – Fendy

2

просто потому, что вы должны подклассифицировать его?

Возможно, в этом контексте House просто недостаточно специфичен; Конечно, все, что в этих отношениях являются дома, но ожидает конкретных типов, таких как Bungalow, Mansion, Apartment и т.д ... Так House служит в качестве полезного категоризации (например, в List<House> или свойство тип House) - но вы никогда не ожидали иметь фактический экземпляр этого базового типа.

+0

Если ожидается подкласс, почему бы не отметить его как виртуальный? Открытие двери в «Бунгало» может отличаться от открытия в «Квартире». – Fendy

+0

@Fendy, который зависит от реального примера - не все методы являются лучшими виртуальными. Некоторые из них, некоторые - нет. –

+0

В данном случае я рассматриваю «OpenDoor» как настоящий пример. И ИМХО, абстрактный класс без абстрактного/виртуального участника - плохой дизайн. – Fendy

1

Я мог представить себе, что какая-то платформа (возможно, в компании) может определять программистов абстрактного класса, должен ли подкласс таким образом, чтобы методы могли быть добавлены в более поздних версиях?

+0

Хммм ...не совсем, я не думаю. –

4

Возможно, вам понадобится общая база для доступа к ссылке, чтобы вы могли обрабатывать список многих типов домов. У вас может быть List<House>, и некоторые из них могут быть BrickHouse другие WoodenHouse, но открытие дверей действует одинаково для всех домов, поэтому имеет смысл поставить метод в базу. Вы объявляете базовый реферат, если нет смысла создавать экземпляр этого класса.

+0

Почему бы не интерфейс тогда? –

+0

@ Это не цифра. Можете ли вы реализовать методы в интерфейсе? –

+0

@Heuster Нет, вы не можете, как я уже упоминал в своем ответе. Тем не менее, этот ответ, похоже, не упоминает об этом ... –

0

Так что базовый класс определяет реализацию. Если реализация является общей для всех производных классов, имеет смысл сохранить ее в абстрактном классе, не дублируя код в производном классе.

Смотрите эту ссылку, имеет некоторую полезную информацию об этом http://www.codeproject.com/Articles/6118/All-about-abstract-classes

1

Только для автоматической реализации вещи для них, так, например, обеспечить реализацию по умолчанию GetHashCode, или, может быть ToString.Кроме того, он позволяет вам добавить метод к интерфейсу, который реализует абстрактный класс, предоставить реализацию по умолчанию, а затем ничего не сломается, а не другой вариант, когда каждый класс ломается, и вы должны исправить все из них вручную.

+0

Оба метода «GetHashCode» и «ToString» могут быть переопределены. Почему бы не отметить это как виртуальное? – Fendy

0

абстрактные классы - это скорее логический класс для наследования, а не использование его как основного для наследования, вы можете использовать абстрактный класс, чтобы рассказать всем, кто наследует от него, иметь определенное свойство или конкретный метод do, Интерфейсы могут делать именно это.

Скажем, у меня есть класс млекопитающих, но класс млекопитающих - это всего лишь абстрактный класс, нет настоящего животного, которое является своего рода млекопитающим, хотя есть много животных (включая людей), которые наследуют «свойства», от него.

Опять же, абстрактное использование, безусловно, зависит от выбора разработчика.

0

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

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

0

Аннотация класс служит в качестве шаблона (может или не может предусматривать реализацию по умолчанию), в то время как ребенок может перезаписывать все, что ему не нравится, или дополнительные методы/свойства/etc.

очень интересный сценарий типа ограничения наследования:

public abstract class MyClass 
{ 
    public void DoSomething() 
    { 
     Console.WriteLine("blah blah"); 
    } 
} 

public class MyClass<T>: MyClass 
{ 
    public T GetSomething() 
    { 
     // return null as T; 
    } 
} 

вы можете увидеть реализацию по умолчанию в базовом классе.

+0

Это действительно общий шаблон для списков объектов MyClass, потому что общие классы не имеют общего базового класса, который можно использовать (кроме объекта). – Aphelion

1

Интересно, что static classes в C# - это действительно sealed и abstract. Цель в этом случае очевидна: разрешить объявлять только статические методы.

+1

Пока * true *, это действительно не относится к вопросу (не-статическому) –

0

Часто базовый класс используется для обеспечения общей функциональности. В зависимости от вашего дизайна эта общая функциональность может быть реализована без зависимостей от участников. В этом случае обычно подклассам не требуются общие члены. В вашем примере класс объектов House используется для простых действий, и я предполагаю, что вам не нужно какое-либо общее состояние дома, например, количество этажей, тип стен (дерево, кирпич и т. Д.). Видя такой класс, я думаю: «Хорошо, этот класс не имеет никакого состояния объекта. Он просто выполняет какое-то действие»

Смежные вопросы