英文:
Is it possible to change an object which was originally created as a subclass object to another subclass object?
问题
例如,我有一个类(Account)和两个子类(BasicAccount 和 PremiumAccount)。
如果我像这样创建一个对象:
Account account1 = new BasicAccount();
是否可能将 account1 的子类更改为 PremiumAccount?
英文:
For example, I have a Class (Account) and 2 subclasses (BasicAccount and PremiumAccount).
If I create an object like this
Account account1 = new BasicAccount();
Is it possible to change account1 subclass to PremiumAccount?
答案1
得分: 1
正如评论中所指出的,这从根本上是不可能的。
解决底层问题的实际方法是通过包信封-信件模式(也称为句柄-主体习语)。
也就是说,您创建一个包装器类,该类实现了公共接口,并将所有方法分派给可以重新赋值的实例变量。
至少,这看起来如下:
class AccountWrapper implements Account {
private Account instance;
private AccountWrapper(Account instance) {
this.instance = instance;
}
public static AccountWrapper createBasicAccount() {
return new AccountWrapper(new BasicAccount());
}
public static AccountWrapper createPremiumAccount() {
return new AccountWrapper(new PremiumAccount());
}
public void upgrade() {
if (instance instanceof PremiumAccount) throw new InvalidStateException();
this.instance = new PremiumAccount(instance); // 复制状态
}
// … 实现 Account 方法并转发到 `instance`。
}
然后您可以像这样使用它:
final AccountWrapper account = AccountWrapper.createBasicAccount();
// …
account.upgrade();
英文:
As noted in comments, that’s fundamentally not possible.
A practical solution to the underlying problem is via the envelope–letter pattern (also known as handle–body idiom).
That is, you create a wrapper class that implements the common interface and dispatches all methods to an instance variable which can be reassigned.
At minimum, this would look as follows:
class AccountWrapper implements Account {
private Account instance;
private AccountWrapper(Account instance) {
this.instance = instance;
}
public static AccountWrapper createBasicAccount() {
return new AccountWrapper(new BasicAccount());
}
public static AccountWrapper createPremiumAccount() {
return new AccountWrapper(new PremiumAccount());
}
public void upgrade() {
if (instance instanceof PremiumAccount) throw new InvalidStateException();
this.instance = new PremiumAccount(instance); // copy state
}
// … implement Account methods and forward to `instance`.
}
Then you can use it like this:
final AccountWrapper account = AccountWrapper.createBasicAccount();
// …
account.upgrade();
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论