更改 和 对象的类.(其他的废话?
Change the class of and object. (Other aproachs?)
我想这样做的时候,我有几种情况。这可能是一个例子:
考虑国际象棋游戏的可能实现。我们定义了抽象类"Piece"和从中继承的类:"主教"牡丹"塔"马"女王"等
我们的牡丹可能即将到达棋盘的尽头,并且可能需要调用该牡丹对象的方法将该对象的类别更改为"女王"、"马"或其他什么。
所以我的问题是,有没有办法在C++或Java中做到这一点?如果没有,用任何其他语言?另外,对于这种情况,还有其他方法吗?
在C++或Java等语言中,我会创建一个"Queen"或"Horse"的新实例,并将"Peon"实例替换为该新实例。
我认为您对对象的看法与对象的使用方式混淆了。 在面向对象的语言中,我们有指示对象实例的内存位置的指针:
Piece pointerToPieceObject = new Peon();
在上面的语句中,pointerToPieceObject
属于"类型"Piece
。 由于Peon
和Queen
都继承自Piece
,因此此指针可以指向以下任何类型的对象实例:
pointerToPieceObject = new Queen();
这是任何面向对象语言都支持的一个非常通用的概念。 这些语言之间的唯一区别是如何处理类型(例如Python与Java)。 这个概念称为多态性,可以用来做比上面的例子更花哨的事情:http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming
您可以使用装饰器模式或策略模式。
带装饰器:
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的答案中提到的另一个实例。
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();
}
}
我看到两个简单的选择:
-
让
type
是一个Pice
设置为Bishop
/Queen
/...这样您就可以轻松更改它。 -
只需删除
Peon
并创建一个新的Queen
/Horse
/...取而代之。我不认为对象标识在这里非常重要。
简短的回答是否定的,你不能更改对象的类。您需要将其替换为所需类的新对象。
对于泛型基本类"升级"或"进化"到更高、更定义的类的情况,您可能希望所有定义更明确的类(骑士、女王、主教)都有一个采用 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);
这是您可能能够改变类的尽可能接近。
- 具有包含其他对象的类的对象创建顺序
- 如何在不使用new的情况下保持在其他对象中创建的对象存活?
- 为什么最后一个推回向量的对象的字段会转移到向量的其他对象?
- 通过向构造函数其他对象引用页面来创建对象
- 如何在 opengl 中仅旋转特定对象而不影响其他对象?
- 推断大多数模板对象的参数,但在调用模板函数时对其他对象显式
- neak_ptr vs unique_ptr参考 - 传递接口inmand tos to其他对象
- 修改对象也会修改同一类的所有其他对象
- 提升序列化仅适用于主要?当我在其他对象中使用时,继续说"has no member named ‘serialize’"
- 当对象被其他对象引用时,关于 const 限定符的微妙问题
- boost::可选 - 对对象使用 boost::in_place,构造器通过引用获取其他对象
- 当对象包含其他对象的向量时,无法设置值
- C 序列化包含其他对象数组的对象
- 如何引用其他对象中的对象
- 如果您称为destructor并将分配的内存再次用于其他对象,会发生什么
- 对象必须包含指针成员才能与其他对象通信
- 访问同一类的其他对象的变量
- 随机数向量的值在放置在其他对象向量内时设置为 0。
- OO 正确性 - 继承层次结构 - 谁创建其他对象使用的对象
- 使用带有纹理的.x文件网格会覆盖其他对象的颜色