c# - 人们如何解决子类初始化方法需要不同数量的参数到他们的父类(super class)?

标签 c# java actionscript-3 oop

假设我有一个游戏,它有一个实体类基类,有一个不带参数的 init 方法。现在我有一个 Wizard 类,但我想传递 2 个参数,比如速度和强度。在 AS3(我相信 Java 和 C#)中,我将不允许这样做——这是一个“不兼容的覆盖”,因为方法签名不匹配。现在我可以只创建一个“initWizard”方法,但是我遇到了每个类的 init 方法可能具有不同名称的问题。

我需要适用于 AS3、Java 或 C# 的解决方案。

最佳答案

AS3 不支持方法重载,但坦率地说,方法重载只是一种语法糖,通常只会引入歧义和不一致。

在Java中,一个方法是由它的名字和它的签名决定的,在AS3中,只由它的名字决定,但是在语义上,两者之间只有很小的区别

protected void init( int a )
protected void init( int a, int b )

protected void init1( int a )
protected void init2( int a, int b )

在 AS3 中,每个名称只能有一个方法,每个类只能有一个构造函数。但是,构造函数不需要具有兼容的签名。在 AS3 中,您可以这样解决问题:

package {
 class A {
  private var a:int;
  public function A(a:int) {
   this.a = a;
  }
  // ... probably some meaningful methods here :)
 }
}
package {
 class B extends A {
  private var b:int;
  public function B(a:int, b:int) {
   super(a);
   this.b = b;
  }
  // ... probably some other meaningful methods here as well :D
 }
}

您还避免了 ewernli 提出的 Java 解决方案中的问题。

编辑:刚刚看到,您坚持不使用构造函数,而是使用具有不同签名的 init 方法。为什么?这违反了 Liskov substitution principle .

编辑2: 我想你有两个选择:

  1. 初始化器的不同名称(这不是最好的主意,而且因为您的子类将公开初始化器,这只能部分工作(不好,请参见上面提到的 LSP))。
  2. 秉承任何类都必须是抽象类或最终类的理念。示例(假设是太空游戏):

一个抽象基类,多个具体子类:

class ShipBase {//in Java you might wanna put the 'abstract' keyword just infront
 //... implementation of some sort
 //... maybe a protected intializer to call by subclasses
 //... no public initializer, since class is abstract
}
final class Fighter extends ShipBase {
 //... public initializer specific to Fighter
 //... other custom behaviour
}
final class Bomber extends ShipBase {
 //... I guess, this is obvious
}

现在您可能会问自己:如果我希望 Fighter 成为一个基类(例如,EliteFighter2000),而且还是一个可实例化的类,该怎么办?简单的。它只是不必如此。

class FighterBase extends ShipBase {
    //... implementation of whatever kind of things fighters have in common
    //... a protected intializer to call by subclasses    
}
final class Fighter extends FighterBase {
    //... public initializer possibly just forwarding to protected initializer
}
final class EliteFighter2000 extends FighterBase {
    //... here goes all the 'elite' stuff
}

这样也比较灵活。您现在可以在不影响 EliteFighter2000 的情况下更改简单的 Fighter,或者您可以决定通过修改 FighterBase 来改变所有战士的共同行为.继承通常是一件危险的事情,并且经常被误解和误用。
坚持这条规则通常有助于避免由于缺乏关注点分离而引入的微妙但通常影响深远的耦合继承。在这种情况下,战斗机通用的任何东西都将在 FighterBase 中实现,而简单的 Fighters 特有的任何东西都在它所属的地方。

问候
回退

关于c# - 人们如何解决子类初始化方法需要不同数量的参数到他们的父类(super class)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3447576/

相关文章:

c# - 用于检查 url 和共享文件路径的正则表达式

c# - Math.log() 使用 c# 给我错误的值

java - 使用 @ResponseBody 的 Http 响应

java - JFace CTabFolder,在选项卡之间切换

apache-flex - 何时在 AS3 的 ByteArray 中使用 writeUTF() 和 writeUTFBytes()

actionscript-3 - 如何指定 ENTER_FRAME 以便对象每 4 帧进入一次?

c# - 不知道这样的主机 —> System.Net.Http.HttpRequestException :

c# - 为什么 "Assert"这个类会有这么多看似多余的方法呢?什么时候应该使用它们?

java - TreeCellRenderer中的标签宽度不正确

actionscript-3 - AS3 -TypeError #1009 - 有什么简单的方法可以找出*哪个*对象引用为空?