Конструктор абстрактного класса в C # - PullRequest
183 голосов
/ 09 апреля 2011

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

Ответы [ 11 ]

258 голосов
/ 09 апреля 2011

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

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

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

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

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

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

230 голосов
/ 09 апреля 2011

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

21 голосов
/ 09 апреля 2011

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

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

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

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

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

5 голосов
/ 09 апреля 2011

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

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

1 голос
/ 12 июня 2014

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

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

0 голосов
/ 19 июня 2017

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

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

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

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

0 голосов
/ 24 января 2017

Существуют две важные функции, которые не позволяют наследовать Абстрактный класс

  1. Абстрактный класс должен иметь абстрактный метод, в противном случае это не абстрактный класс

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

0 голосов
/ 28 июня 2016

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

0 голосов
/ 03 сентября 2013

Определение конструктора с открытым или внутренним классом хранения в наследуемом конкретном классе 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);.

0 голосов
/ 03 сентября 2013

Я тоже хочу сделать блеск на абстрактной поверхности. Весь ответ охватил почти все.Тем не менее мои 2 цента

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

  1. Вы, любой клиент / потребитель этого класса, не можете создать объект этого классаозначает, что это конструктор никогда не вызовет.Его производный класс может выбирать, какой конструктор вызывать. (Как показано в некотором ответе)
  2. Может иметь абстрактную функцию.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...