inheritance - Почему я не могу создать абстрактный конструктор на абстрактном классе C#?




oop constructor abstract-class (8)

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

public abstract class A 
{ 
    abstract A MakeAInstance(int a, int b); 
} 

public class B : A 
{ 
    // Must implement:
    override A MakeAInstance(int a, int b) {
        // Awesome way to create a B instance goes here
    }
} 

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

public abstract class A
{
    abstract A(int a, int b);
}

Однако я получаю сообщение о том, что абстрактный модификатор недействителен в этом элементе. Моя цель состояла в том, чтобы заставить такой код сделать это.

public class B : A
{
    public B(int a, int b) : base(a, b)
    {
        //Some other awesome code.
    }
}

Это все код C # .NET. Может кто-нибудь мне помочь?

Обновление 1

Я хотел кое-что добавить. То, что я закончил, было этим.

private A() { }

protected A(int a, int b)
{
    //Code
}

Это то, что говорят некоторые люди, по умолчанию является приватным, а классу необходимо реализовать конструктор. Однако это не делает FORCE конструктором с сигнатурой A (int a, int b).

public abstract class A
{
    protected abstract A(int a, int b)
    {


    }
}

Обновление 2

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


Несколько причин:

1) Конструкторы не наследуются, поэтому вы не можете их переопределить.

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


не уверен, помогает ли это, но я считаю, что это будет решением вашей проблемы:

public class A
{
  public A(int a, int b)
  {
    DoSomething(int a, int b);
  }

  virtual public void DoSomething(int a, int b)
  {

  }
}

public class B : A
{
  override public void DoSomething(int a, int b)
  {
    //class specific stuff
  }
}

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


Вы не можете применять подпись конструктора, так как каждый производный класс может (должен!) Определять свой собственный конструктор (ы), и они могут принимать любые параметры, которые им нравятся.

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


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

Если вы думаете об этом, это имеет смысл, поскольку вы всегда называете конструктором дочернего класса (с новым оператором) и никогда не базовым классом.

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


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

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

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


надеюсь, что это поможет кому-то newb, поскольку я ищу, чтобы сделать «обычный» публичный класс с ctor, который принимает аргумент, а затем мне нужно было сделать его дочерним классом, поэтому мне понадобился пустой ctor для него.

Я не знал об этом раньше: если вы создаете защищенный ctor, тогда класс child видит его, но остальная часть программы не видит его (я думаю, что моя путаница с тех пор, как в asp.net я вижу все защищенные на странице aspx, которые наследуются от cs ...)


Да, конечно, вы можете добавить один, как уже упоминалось, для инициализации абстрактных переменных класса. НО, если вы явно не объявляете одно, у него всегда есть неявный конструктор для «Constructor Chaining».





c# inheritance oop constructor abstract-class