更改类和对象。 (其他方法?)

时间:2012-06-29 12:58:36

标签: java c++ class inheritance runtime

我有几种情况需要这样做。这可能就是一个例子:

考虑国际象棋游戏的可能实现。我们定义抽象类'Piece'和从它继承的类:'bishop''peon''taft'' horse''ques'等

我们可能让我们的peon即将到达棋盘的末端,并且可能需要一个调用该peon对象​​的方法将该对象的类更改为“Queen”,“horse”或其他任何东西。

所以我的问题是,有没有办法在C ++或Java中做到这一点?如果没有,用其他语言? 此外,这种情况一般还有其他方法吗?

6 个答案:

答案 0 :(得分:10)

在C ++或Java等语言中,我会创建一个新的'Queen'或'Horse'实例,并用新的实例替换'Peon'实例。

答案 1 :(得分:2)

我认为您对对象的看法与对象的使用方式相混淆。在面向对象的语言中,我们有指针指示对象实例的内存位置:

Piece pointerToPieceObject = new Peon();

在上面的陈述中,pointerToPieceObject属于“类型”Piece。由于PeonQueen都从Piece继承,因此该指针可以指向任何这些类型的对象实例:

pointerToPieceObject = new Queen();

这是任何面向对象语言都支持的非常通用的概念。这些语言之间的唯一区别是如何处理类型(例如Python与Java)。这个概念被称为多态,可以用来做比上面例子更多的事情:http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming

答案 2 :(得分:0)

您可以使用decorator patternstrategy 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)

我看到两个简单的选择:

  1. type成为Pice字段,它设置为{{1}的实例(可能是单例,例如实现为枚举) } / Bishop / ...通过这种方式,您可以轻松更改它。

  2. 只需移除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);

这就像你可能能够改变课程一样接近。