Подтвердить что ты не робот

Абстрактный конструктор в С#

Возможный дубликат:
Почему я не могу создать абстрактный конструктор на абстрактном классе С#?

Почему я не могу объявить абстрактный конструктор моего класса следующим образом:

public abstract class MyClass {
    public abstract MyClass(int param);
}
4b9b3361

Ответ 1

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

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

public abstract class Foo
{
     public string Name { get; private set; }

     protected Foo( string name )
     {
         this.Name = name;
     }
}

public class Bar : Foo
{
     public Bar() : base("bar")
     {
        ...
     }
}

Ответ 2

Вы не можете объявить его abstract, но вы можете иметь конструктор в своем абстрактном классе; просто удалите слово abstract и предоставите ему тело.

Ответ 3

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

IF в будущей версии С#, генераторы расширены, чтобы разрешать вызовы конструкторов, не являющихся стандартными, через параметр общего типа, тогда возможны полиморфные вызовы конструкторам, а также добавлены виртуальные и абстрактные конструкторы.

Ответ 4

Конструкторы ближе к статическим методам, а не к "обычным" методам. Как и статические методы, они могут быть перегружены, но не overriden. То есть, они не наследуются, но могут быть переопределены.

public BaseClass
{
   public BaseClass( String s ) { ... }
   public static void doIt ( String s ) { ... }
}

public SubClass extends BaseClass
{
   public SubClass( String s )  { ... }
   public static void doIt ( String s ) { ... }
}

public SubClass2 extends BaseClass
{
}

new SubClass( "hello" );
SubClass.doIt( "hello" ); 

new SubClass2( "hello" ); // NOK
SubClass2.doIt( "hello" ); // NOK

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

Вы можете даже думать о конструкторе как статический factory метод (и см. соответствующий шаблон):

  MyClass obj = new MyClass(); // the way it is
  MyClass obj = MyClass.new(); // think of it like this

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

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

Ответ 5

Поскольку абстрактные конструкторы не поддерживаются.

Но абстрактный класс может иметь конструктор.

Ответ 6

Что не так с этим:

public abstract class MyClass {
    protected MyClass(int param)
    {
    }
}

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

Ответ 8

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