Почему C# допускает абстрактный класс без абстрактных участников?

Спецификация C#, разделите 10.1.1.1, состояния:

Абстрактный класс разрешается (но не требуется) содержать абстрактных участников.

Это позволяет мне создавать классы как это:

public abstract class A
{
    public void Main() 
    {
        // it's full of logic!
    }
}

Или еще лучше:

public abstract class A
{
    public virtual void Main() { }
}

public abstract class B : A
{
    public override sealed void Main()
    {
        // it's full of logic!
    }
}

Это - действительно реальный класс; это только абстрактно, поскольку нельзя инстанцировать его. Например, если я хотел выполнить логику в B.Main() Я должен был бы сначала получить экземпляр B, который невозможен.

Если наследники не должны на самом деле обеспечивать реализацию, то почему вызов это краткий обзор?

Другими словами, почему C# позволяет абстрактный класс только с конкретными участниками?

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

20
задан Justin R. 14 April 2017 в 22:41
поделиться

9 ответов

Возможно, хорошим примером является общий базовый класс, который предоставляет общие свойства и, возможно, другие члены для производных классов, но не представляет конкретный объект. Например:

public abstract class Pet
{
    public string Name{get;set;}
}

public class Dog : Pet
{
    public void Bark(){ ... }
}

У всех домашних животных есть имена, но домашнее животное само по себе является абстрактным понятием. Примером домашнего животного должна быть собака или какое-то другое животное.

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

23
ответ дан 29 November 2019 в 23:27
поделиться

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

Например:

public abstract class FourLeggedAnimal
{

    public void Walk()
    {
        // most 4 legged animals walk the same (silly example, but it works)
    }

    public void Chew()
    {

    }
}

public class Dog : FourLeggedAnimal
{
    public void Bark()
    {
    }
}

public class Cat : FourLeggedAnimal
{
    public void Purr()
    {
    }
}
11
ответ дан 29 November 2019 в 23:27
поделиться

Вы сказали это - потому что вы не можете его инстанцировать; он предназначен только для шаблона.

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

Этот выбор дизайна может быть связан с созданием сущностей, которые являются (рискуя смешать терминологию) абстракциями реальных объектов, и с удобством чтения. Вы можете захотеть объявить параметры типа Car, но не хотите, чтобы объекты объявлялись как Car - вы хотите, чтобы каждый объект типа Car инстанцировался как Truck, Седан, Купе или Родстер. Тот факт, что Car не требует от наследников добавления реализации, не умаляет его ценности как абстрактной версии своих наследников, которая сама не может быть инстанцирована.

3
ответ дан 29 November 2019 в 23:27
поделиться

Что касается использования, то использование abstract в объявлении класса, но без абстрактных членов, аналогично использованию класса public , но используя protected в своих конструкторах. Оба заставляют класс быть производным, чтобы он был создан.

Однако, что касается самодокументируемого кода, помечая класс abstract , он информирует других, что этот класс никогда не предназначен для создания отдельного экземпляра, даже если он не имеет виртуальных или абстрактные участников. В то время как защита конструкторов не делает такого утверждения.

1
ответ дан 29 November 2019 в 23:27
поделиться

Компилятор не препятствует реализации-логике, но в вашем случае я бы просто опустил abstract ?! BTW некоторые методы могут быть реализованы с помощью { throw Exception("must inherit"); } и компилятор не сможет отличить полностью реализованные классы и функции, включающие только throw.

0
ответ дан 29 November 2019 в 23:27
поделиться

Вот потенциальная причина:

Супертип слоя

Не редкость, когда все объекты в слое имеют методы, которые вы не хотите дублировать по всей системе. Вы можете перенести все это поведение в общий Layer Супертип.

-- Мартин Фаулер

Нет причин предотвращать наличие только конкретных методов в абстрактном классе - это просто менее распространено. Супертип Layer - это случай, когда это может иметь смысл.

0
ответ дан 29 November 2019 в 23:27
поделиться

Я вижу абстрактные классы, служащие двум основным целям:

  • Неполный класс, который должен быть специализирован для предоставления некоторой конкретной услуги. Здесь абстрактные члены будут необязательными .Класс будет предоставлять некоторые службы, которые могут использоваться дочерними классами, и может определять абстрактные члены, которые он использует для предоставления своих услуг, как в Template Method Pattern . Этот тип абстрактного класса предназначен для создания иерархии наследования .

  • Класс, который предоставляет только статические служебные методы . В этом случае абстрактные члены вообще не имеют смысла. C # поддерживает это понятие с помощью статических классов , они неявно абстрактны и запечатаны. Этого также можно достичь с помощью закрытого класса с частным конструктором.

0
ответ дан 29 November 2019 в 23:27
поделиться

Я думаю, что несколько более точное представление вашего вопроса будет: Почему C # допускает абстрактный класс с только конкретными членами?

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

8
ответ дан 29 November 2019 в 23:27
поделиться

Абстрактное означает предоставление абстракции поведения. Например, Автомобиль - это абстрактная форма. У него нет реального экземпляра, но мы можем сказать, что Vehicle имеет ускоряющееся поведение. В частности, Ford Ikon - это транспортное средство, а Yamaha FZ - это транспортное средство. Оба они имеют ускоряющееся поведение.

Если вы сейчас сделаете это в форме класса. Автомобиль - это абстрактный класс с методом ускорения. Хотя вы можете / не можете предоставлять какой-либо абстрактный метод. Но бизнес-потребность состоит в том, чтобы не создавать экземпляр Vehicle. Следовательно, вы делаете это абстрактным. Два других класса - Ikon и FZ - это конкретные классы, производные от класса Vehicle. У этих двоих будут свои свойства и поведение.

1
ответ дан 29 November 2019 в 23:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: