我有几种情况需要这样做。这可能就是一个例子:
考虑国际象棋游戏的可能实现。我们定义抽象类'Piece'和从它继承的类:'bishop''peon''taft'' horse''ques'等
我们可能让我们的peon即将到达棋盘的末端,并且可能需要一个调用该peon对象的方法将该对象的类更改为“Queen”,“horse”或其他任何东西。
所以我的问题是,有没有办法在C ++或Java中做到这一点?如果没有,用其他语言? 此外,这种情况一般还有其他方法吗?
答案 0 :(得分:10)
在C ++或Java等语言中,我会创建一个新的'Queen'或'Horse'实例,并用新的实例替换'Peon'实例。
答案 1 :(得分:2)
我认为您对对象的看法与对象的使用方式相混淆。在面向对象的语言中,我们有指针指示对象实例的内存位置:
Piece pointerToPieceObject = new Peon();
在上面的陈述中,pointerToPieceObject
属于“类型”Piece
。由于Peon
和Queen
都从Piece
继承,因此该指针可以指向任何这些类型的对象实例:
pointerToPieceObject = new Queen();
这是任何面向对象语言都支持的非常通用的概念。这些语言之间的唯一区别是如何处理类型(例如Python与Java)。这个概念被称为多态,可以用来做比上面例子更多的事情:http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming
答案 2 :(得分:0)
您可以使用decorator pattern或strategy pattern。
装饰者:
interface ChessPiece {
Set<Move> getPossibleMoves();
Image getAppearance();
}
class Pawn implements ChessPiece {
...
}
class Decorator implements ChessPiece {
ChessPiece decorated;
public Decorator(ChessPiece decorated_) {
this.decorated = decorated_;
}
@override
Set<Move> getPossibleMoves() {
Set<Move> result = decorated.getPossibleMoves();
// alter result
return result;
}
}
需要时,将Pawn
实例替换为Decorated
实例。 所以它仍然涉及用OpenSause's回答中提到的另一个实例替换一个实例。
ChessPiece pawn = new Pawn;
...
pawn = new Decorated(pawn);
当你提前计划时,你可以使用策略它仍然没有真正改变类:
interface PossibleMovesStrategy {
Set<Move> getPossibleMoves();
}
interface AppearanceStrategy {
Image getAppearance();
}
class ChangingChessPiece extends ChessPiece {
PossibleMovesStrategy posMoves;
AppearanceStrategy appearance;
@override
Set<Move> getPossibleMoves() {
return posMoves.getPossibleMoves();
}
@override
Image getAppearance() {
return appearance.getAppearance();
}
}
答案 3 :(得分:0)
我看到两个简单的选择:
让type
成为Pice
的字段,它设置为{{1}的实例(可能是单例,例如实现为枚举) } / Bishop
/ ...通过这种方式,您可以轻松更改它。
只需移除Queen
并在其位置创建新的Peon
/ Queen
/ ....我不认为对象身份在这里非常重要。
答案 4 :(得分:0)
简短的回答是否定的,你无法改变一个对象的类。您需要将其替换为所需类的新对象。
答案 5 :(得分:0)
对于泛型,基本类“升级”或“演变”到更高,更定义的类的情况,您可能希望所有更多定义的类(Knight,Queen,Bishop)具有一个构造函数, Peon类,在这种情况下是Pawn。如果Pawn和Knight和Queen以及所有部分都有一个共同的基础,那么在Knight / Queen / etc的构造函数中,您将可以访问该基类中的受保护变量,并可以将Pawn克隆到下一个类中。
class Pawn extends ChessPiece {...}
class Queen extends ChessPiece {
public Queen(Pawn p) {
// DON'T accept a ChessPiece unless you want
// knights or rooks to become queens.
// copy p's variables here
}
}
ChessPiece piece= new Pawn();
// Sometime later...
if (piece is Pawn)
piece = new Queen((Pawn)piece);
这就像你可能能够改变课程一样接近。