【发布时间】:2017-08-17 03:36:54
【问题描述】:
问题
如何使基础构造函数在派生类中调用。当您不实现抽象方法时,IDE 会显示错误消息,并且您理解应该实现这个:) 当程序员不调用 base() 时,我想要一些消息。此外,如果层次结构很深,我需要调用第一个基类构造函数。也许有一些解决方法可以自动进行此调用,或者有一些解决方案可以让程序员说他需要进行此调用。如您所见,在abstract class Shape 构造函数中调用了此设置方法SetShapeWorker。我需要在所有派生类中调用这个构造函数。
说明
我有形状。我决定用命令模式实现一些算法,所以 Shape 是接收器。在这种情况下,它也是一个调用者,因为在某些方法中我需要从 ShapeWorker 调用一些方法。这里是SizeDialog。查看Shape 中的构造函数,我有shapeWorker 变量,我在一些Shape 方法中使用该方法-查看SetSizeWorker() 的默认实现。
我想用具体的接收器——方形或矩形来初始化 ShapeWorker。所以我声明了astract SetShapeWorker,如果另一个程序员或者我在几周后添加了三角形,IDE 将显示我需要实现受保护的 SetShapeWorker 的消息,程序员应该明白他需要写这样的东西:
class Triangle : Shape {
//adding the triangle shape worker
public override SetShapeWorker() {
shapeWorker = new ShapeTriangleWorker();
shapeWorker.SetReceiver(this);
}
}
在此之后,所有命令调用程序方法都应该工作。如您所见,此 set 方法在 abstract class Shape 构造函数中调用。所以我想在所有派生类中调用这个构造函数。
以及我进行此初始化的原因:使用演员表(receiver as Rectangle).SetSize(a,b),(receiver as Square).SetSize(a)。 Bob叔叔在其中一个视频中说,要进行这些演员表,我应该确保演员表是有效的,我同意他的观点:) 我尝试将其设置为专用于用户界面SetShapeWorker,程序员应该设置具体的接收器。
代码
abstract class Shape {
private ShapeWorker shapeWorker;
public Shape() {
SetShapeWorker();
}
private bool isSet = false;
public IsSet {
get {
return isSet;
}
}
public abstract int Square();
protected abstract void SetShapeWorker();
public void SetSizeWorker() {
if(shapeWorker != null) {
shapeWorker.SizeDialog();
}
}
}
class Square : Shape {
private int a;
public Square() {
}
public SetSize(int a) {
this.a = a;
isSet = true;
}
public override int Square() {
return a*a;
}
protected override SetShapeWorker() {
shapeWorker = new ShapeSquareWorker();
shapeWorker.SetReceiver(this);
}
}
class Rectangle : Shape {
private int a, b;
private Rectangle() : base() {
}
public SetSize(int a, int b) {
this.a = a;
this.b = b;
isSet = true;
}
public override int Square() {
return a*b;
}
protected override SetShapeWorker() {
shapeWorker = new ShapeRectangleWorker();
shapeWorker.SetReceiver(this);
}
}
abstract class ShapeWorker
{
public Shape receiver;
public abstract void SetReceiver(Shape receiver) {
this.receiver = receiver;
}
public abstract void SizeDialog();
public abstract int StrangeCountSquare();
public int getDeltaSquare() {
if(receiver.IsSet == false) {
SizeDialog();
return StrangeCountSquare();
}
}
}
class ShapeSquareWorker {
public override void SizeDialog() {
int a;
Console.WriteLine("Enter the a: ");
Int32.TryParse(Console.ReadLine(), out a);
(receiver as Square).SetSize(a);
}
public override int StrangeCountSquare() {
return receiver.Square() + 10;
}
}
class ShapeRectangleWorker {
public override void SizeDialog() {
int a, b;
Console.WriteLine("Enter the a: ");
Int32.TryParse(Console.ReadLine(), out a);
Console.WriteLine("Enter the b: ");
Int32.TryParse(Console.ReadLine(), out b);
(receiver as Rectangle).SetSize(a,b);
}
public override int StrangeCountSquare() {
return receiver.Square() + 20;
}
}
顺便说一句 现在我正在学习 SOLID 和模式,stackoverflow 中最适合讨论的地方在哪里? F.e.如果我想讨论混合一些模式的有用方法。请在评论中回答。
【问题讨论】:
-
可能
ShapeSquareWorker和ShapeRectangleWorker应该是ShapeWorker的派生词... -
我不确定我是否遵循,但是当您在基类中有一个构造函数时,它将始终被调用,无论开发人员是否将其显式化。
-
你的代码有什么问题?将调用 SetShapeWorker,因为将在基类中调用默认构造函数。
-
在 .NET 的基类中调用构造函数不是可选的。您可以指定调用哪一个,但如果不指定,则将调用默认的无参数构造函数。如果你没有那个,并且没有指定要调用哪个其他构造函数,那么你的派生类会出现编译器错误。你还想要什么?你想要求程序员显式写出对
base()的调用,即使编译器会为你注入它? -
我只是注意到你的设计中有一个Anti-pattern:Circular Dependency。
Shape指的是ShapeWorker,ShapeWorker指的是Shape。这不是正确的 OO。
标签: c# oop inheritance design-patterns constructor