我有一个抽象基类,它包含一些字段和一些作用于这些字段的方法。例如:
public abstract class A
{
protected double _field;
public double SquaredField { get { return _field * _field; } }
... some other abstract methods
}
我想在其构造函数中强加A初始化_field的所有子元素
public class B : A
{
public B(double field)
{
_field = Math.Sqrt(field);
}
... some other method implementations
}
实现这一目标的正确模式是什么?
- 编辑
我最终做的是:
public abstract class A
{
protected readonly double _field;
public A(double field)
{
_field = field;
}
public double SquaredField { get { return _field * _field; } }
... some other abstract methods
}
public class B : A
{
public B(double field) : base(field)
{
}
public static B CreateNew(double val)
{
return new B(Math.Sqrt(field));
}
... some other method implementations
}
答案 0 :(得分:10)
根本不要将字段公开给派生类。而是创建受保护的抽象属性:
public abstract class A
{
protected double Field { get; }
public double SquaredField { get { return Field * Field; } }
}
或者,如果字段对于特定实例应始终保持不变,请将其设为构造函数参数并将其保持为私有:
public abstract class A
{
private readonly double _field;
public double SquaredField { get { return _field * _field; } }
protected A(double field)
{
_field = field;
}
}
答案 1 :(得分:2)
不要让类A
具有无参数构造函数:
public abstract class A
{
protected double _field;
public double SquaredField { get { return _field * _field; } }
// Require any fields that must be initialized in the base class's
// constructor. If there are a lot of such fields, consider encapsulating
// them all in their own class, e.g. AArgs.
protected A(double field)
{
_field = field;
}
}
public class B : A
{
// You must call a base class constructor as below, because class A
// no longer has a parameterless constructor to use by default.
public B(double field)
: base(field)
{
}
}
如果无法在构造函数中进行初始化,则可以将该字段设置为抽象属性:
public abstract class A
{
protected abstract double Field { get; }
public double SquaredField { get { return Field * Field; } }
}
现在,派生类必须实现该属性,因此您可以为依赖的SquaredField
属性做好准备。我会更改名称,因为它们不再是字段了。
答案 2 :(得分:2)
这可能是一组字段比A
本身更紧密耦合的信号,所以应该移到一个类,比如AParams
。
然后在A
中,您可以声明abstract protected AParams createParams()
方法。
答案 3 :(得分:1)
您可以使用单独的抽象函数来完成此任务。子类将被迫实现它。
public abstract class A
{
protected double _field;
protected A()
{
InitializeField();
}
protected abstract void InitializeField();
public double SquaredField { get { return _field * _field; } }
}
public class B : A
{
protected override void InitializeField()
{
// Initialize...
}
}