Конструктор абстрактного класса в С#

Почему возможно написать конструктор для абстрактного класса в С#?
Насколько я знаю, мы не можем создать экземпляр абстрактного класса.. так что это такое? Вы не можете создать экземпляр класса, не так ли?

Ответ 1

Потому что может быть стандартный способ, которым вы хотите создавать данные в абстрактном классе. Таким образом, вы можете иметь классы, которые наследуют от этого класса, вызвать базовый конструктор.

public abstract class A{

    private string data;

    protected A(string myString){
      data = myString;
    }

}

public class B : A {

     B(string myString) : base(myString){}

}

Ответ 2

Насколько я знаю, мы не можем создать абстрактный класс

Там ваша ошибка. Конечно, вы можете создать экземпляр абстрактного класса.

abstract class Animal {}
class Giraffe : Animal {}
...
Animal animal = new Giraffe();

Там есть экземпляр Animal. Вы создаете абстрактный класс, создавая из него конкретный класс и создавая его. Помните, что экземпляр производного конкретного класса также является экземпляром его абстрактного базового класса. Экземпляр Жирафа также является экземпляром Animal, даже если Animal является абстрактным.

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

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

Ответ 3

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

abstract class Foo
{
    public DateTime TimeCreated {get; private set;}

    protected Foo()
    {
         this.TimeCreated = DateTime.Now;
    }
}

abstract class Bar : Foo
{
    public Bar() : base() //Bar constructor must call Foo parameterless constructor.
    { }
}

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

Ответ 4

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

Любой класс, который наследуется от вашего абстрактного базового класса, будет обязан вызывать базовый конструктор.

Ответ 5

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

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

Ответ 6

Вы можете создать экземпляр после всех методов. Тогда будет вызываться конструктор.

Ответ 7

Я тоже хочу немного осветить абстрактную поверхность Весь ответ покрыл почти все. Еще мои 2 цента

абстрактные классы являются нормальными классами с несколькими исключениями

  • Вы любой клиент/покупатель этого класса не можете создать объект этого class, он никогда не означает, что конструктор никогда не будет звонить. Его производный класс может выбрать, какой конструктор вызвать. (Как показано в некотором ответе)
  • Он может иметь абстрактную функцию.

Ответ 8

Определение конструктора с открытым или внутренним классом хранения в наследуемом конкретном классе Thing эффективно определяет два метода:

  • Метод (который я назову InitializeThing), который действует на this, не имеет возвращаемого значения и может быть вызван только из методов Thing CreateThing и InitializeThing и подклассов 'InitializeXXX.

  • Метод (который я назову CreateThing), который возвращает объект указанного типа конструктора и по существу ведет себя как:

    Thing CreateThing(int whatever)
    {
        Thing result = AllocateObject<Thing>();
        Thing.initializeThing(whatever);
    }
    

Абстрактные классы эффективно создают методы только первой формы. Понятно, что нет причин, по которым два описанных выше "метода" должны иметь одинаковые спецификаторы доступа; на практике, однако, нет способа указать их доступность по-разному. Обратите внимание, что с точки зрения реальной реализации, по крайней мере в .NET, CreateThing на самом деле не реализуется как вызываемый метод, а вместо этого представляет собой кодовую последовательность, которая вставлена ​​в оператор newThing = new Thing(23);.

Ответ 9

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

Ответ 10

От https://msdn.microsoft.com/en-us/library/ms182126.aspx

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

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

Однако, что упомянутый компилятор VS не будет жаловаться (с правилами по умолчанию) при объявлении публичных конструкторов в абстрактных классах, однако он не позволит создать новый экземпляр.

Ответ 11

Вы абсолютно правы. Мы не можем создать экземпляр абстрактного класса, потому что абстрактные методы не имеют тела, т.е. Реализация для абстрактных методов невозможна. Но могут быть некоторые сценарии, когда вы хотите инициализировать некоторые переменные базового класса. Вы можете сделать это, используя базовое ключевое слово, предложенное @Rodrick. В таких случаях нам нужно использовать конструкторы в нашем абстрактном классе.

Ответ 12

Существуют две следующие важные функции, которые предотвращают наследование абстрактного класса

  • Абстрактный класс должен иметь абстрактный метод, иначе он не является абстрактным классом

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