Как объявить конструкторы в базовых классах, чтобы подклассы могли использовать их, не объявляя их?
Я хочу, чтобы подкласс использовал конструкторы своего родителя. Но, кажется, мне всегда нужно определять их снова в подклассе, чтобы это работало, вот так:
public SubClass(int x, int y) : base (x, y) {
//no code here
}
Поэтому мне интересно, правильно ли я объявляю конструктор в родительском классе, или нет прямого наследования конструктора вообще?
4 ответа
Вы не делаете ничего плохого.
В C# конструкторы экземпляров не наследуются, поэтому их правильное объявление в виде наследуемого типа и связывание с базовым конструктором.
Из спецификации §1.6.7.1:
В отличие от других членов, конструкторы экземпляров не наследуются, и у класса нет конструкторов экземпляров, кроме тех, которые фактически объявлены в классе. Если конструктор экземпляра не предоставлен для класса, то автоматически предоставляется пустой конструктор без параметров.
Я знаю, что это не дает прямого ответа на ваш вопрос; однако, если большинство ваших конструкторов просто вводят новый параметр в предыдущем конструкторе, вы можете воспользоваться дополнительными аргументами (введенными в C# 4), чтобы уменьшить количество конструкторов, которые вы должны определить.
Например:
public class BaseClass
{
private int x;
private int y;
public BaseClass()
: this(0, 0)
{ }
public BaseClass(int x)
: this(x, 0)
{ }
public BaseClass(int x, int y)
{
this.x = x;
this.y = y;
}
}
public class DerivedClass : BaseClass
{
public DerivedClass()
: base()
{ }
public DerivedClass(int x)
: base(x)
{ }
public DerivedClass(int x, int y)
: base(x, y)
{ }
}
Выше может быть уменьшено до:
public class BaseClass
{
private int x;
private int y;
public BaseClass(int x = 0, int y = 0)
{
this.x = x;
this.y = y;
}
}
public class DerivedClass : BaseClass
{
public DerivedClass(int x = 0, int y = 0)
: base(x, y)
{ }
}
И это все равно позволит вам инициализировать оба BaseClass
а также DerivedClass
с любым количеством аргументов:
var d1 = new DerivedClass();
var d2 = new DerivedClass(42);
var d3 = new DerivedClass(42, 43);
Конструкторы не наследуются от базового класса до производного. Каждый конструктор должен сначала вызвать базовый класс ctor. Компилятор знает только, как вызвать ctor без параметров. Если в базовом классе нет такого ctor, вы должны вызвать его вручную.
Поэтому мне интересно, не правильно ли я объявляю конструктор в родительском классе, потому что это кажется глупым.
Если базовый класс не имеет конструктора по умолчанию, вы должны переопределить его в дочернем классе. Вот как ООП работает в.NET.