我需要如何重组或重构代码,以便可以使用嵌入和继承的对象以最少的代码重复按预期工作。这段代码只是一个例子,我认为这是我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;
}
}
该例子是在书本一样,几乎所有的公共基类相同
Car
和Engine
......当我加入特殊类,它们像基地继承Racecar : Car
和TurboEngine : Engine
和属性添加到像升压专业类,TurboEngine
我会遇到同样的问题,当我想要使用基类中尽可能多的代码和方法,而又不覆盖几乎所有方法。
您遇到的问题是面向对象设计的经典问题。OO非常适合于对派生类更具体但又不引入限制的情况进行建模。赛车比汽车更具体,但是“只有涡轮发动机的赛车”限制了您可以在汽车中安装的发动机种类。
没有明显的解决办法。我在博客上写了一系列帖子,更详细地描述了该问题以及人们尝试解决该问题的一些方式。您可能会发现这很有趣。
http://ericlippert.com/2015/04/27/wizards-and-warriors-part-one/
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句