失去继承和多态性

法尔科·亚历山大(Falco Alexander)

我需要如何重组或重构代码,以便可以使用嵌入和继承的对象以最少的代码重复按预期工作。这段代码只是一个例子,我认为这是我OOP思维中的一个基本错误...

该示例几乎与书籍(如Car,Engine和Driver)中的所有常见基类相同:当我添加从基类继承的特殊类(如Racecar:Car和TurboEngine:Engine)并将属性添加到特殊类(如boost到TurboEngine)时,当我想使用基类中尽可能多的代码和方法而不覆盖几乎所有方法时,也会遇到相同的问题。

我已经将字段重构为属性,并尝试使用new和,override但逻辑问题保持不变。

如果该代码太多,我可以尝试将其缩短为更多我遇到的单一问题。

示例代码显示了问题。向上/向下投射将无济于事。我想这更多是一个基本的思维错误,因为对于一个古老的汇编人员来说,OOP编程很难学习。

编辑----更新:

好吧,这是设计使然。https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science) https://en.wikipedia.org/wiki/Liskov_substitution_principle

我现在感到有些松懈……停留在那里并想:不可能是真的。根据开发人员的经验水平,应该有更多的地方指向,收集和演示这些常见的错误同样在许多书中,它远非突出。现在知道正确的用语了,我发现了更多。但是仍然有许多深入的技术说明不适合新手。这样可以节省很多时间:)

var root = new Vector2D(0,0);

GameField2D fGame = new GameField2D(10,10);
fGame.Init();
fGame.Field[1,1].ParentPoint = root;

fGame.Field[1,1].Color = 1; //<--ERROR to be expected
var test = (TetrisField2D)fGame; //<---ERROR cast not possible

TetrisField2D fTetris = new TetrisField2D(10,10);
fTetris.Init();
fTetris.Field[1,1].ParentPoint = root; //<--ERROR Nullreference because only base class field is initiated.

这些是类:

继承者:

public class TetrisField2D: GameField2D {
    public int Lifes;
    public TetrisPoint[,] Field; //I want of course Tetrispoints with color

    public TetrisField2D(): base(){}
    public TetrisField2D(int x,int y) : base (x,y) {}
}

基类

public class GameField2D { //"generic"
    public GamePoint[,] Field;
    private int size;

    //CTORs
    public GameField2D(){
      Field = new GamePoint[9,9];
      size = 10;
    }
    public GameField2D(int x,int y){
      Field = new GamePoint[x-1,y-1];
      size= x-1;
    }
    public GameField2D(GamePoint[,] f){
      Field = f;
      size = f.GetLength(0);
    }
    public void Init() {
      for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            Field[i,j] = new GamePoint();
        }
      }
    }
}

包含的点类:

public class TetrisPoint : GamePoint{
  public int Color;

  public TetrisPoint(){}
  public TetrisPoint(int x, int y, int col) : base(x,y) {
    Color = col;
  }
}
public class GamePoint   { 
  public Vector2D ParentPoint;
  public bool Appears;
  public int IsUsed;

  public GamePoint(){   }   
  public GamePoint(int x, int y, bool a=false) {
    this.ParentPoint = new Vector2D(x,y); 
    Appears = a;
   }
}

public struct Vector2D {
   public int X,Y;
   public Vector2D(int x,int y) {
        this.X=x;
        this.Y=y;
   }
}
埃里克·利珀特

该例子是在书本一样,几乎所有的公共基类相同CarEngine......当我加入特殊类,它们像基地继承Racecar : CarTurboEngine : Engine和属性添加到像升压专业类,TurboEngine我会遇到同样的问题,当我想要使用基类中尽可能多的代码和方法,而又不覆盖几乎所有方法。

您遇到的问题是面向对象设计的经典问题。OO非常适合于对派生类更具体又不引入限制的情况进行建模赛车比汽车更具体,但是“只有涡轮发动机的赛车”限制了您可以在汽车中安装的发动机种类。

没有明显的解决办法。我在博客上写了一系列帖子,更详细地描述了该问题以及人们尝试解决该问题的一些方式。您可能会发现这很有趣。

http://ericlippert.com/2015/04/27/wizards-and-warriors-part-one/

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章