是否有一种设计模式,我可以使一个对象具有某种状态,在那里他作为一个扩展对象开始,但过了一段时间后又转回到它的超级。
例如 - 部分文件从文件继承,在完成后它将成为文件。
答案 0 :(得分:2)
Java中没有类型变异(公平地说,我不能想到任何具有它的现代语言)。
你可能会做什么,但显然不完全相同:
new Float(new Double(2));
)。请注意,这不会更改初始对象,因此您必须再次分配包含它的变量。type
添加enum
变量,指示对象的性质。对于大多数用途来说它足够了(并且可以帮助您避免构建繁重的类型层次结构)。 现在,你需要类型变异吗?如果你只需要处理你的对象,就像它是超类的直接实例一样,你就可以做到。与类型变异的主要区别在于您调用重写的方法,但如果类型层次结构设计正确,则通常很好。
假设我设计了一个PartialFile类(假设名称正确定义它是什么),而不是使用继承,我会使用组合:我会创建一个装饰类,其实例将具有变量{{1 }}
答案 1 :(得分:1)
这个问题存在缺陷 - 扩展Object
始终是其超类的一个实例。
在您的示例中,以下内容有效...
public class PartialFile extends File{
// methods
}
PartialFile partFile = new PartialFile();
// do operations on partFile
File file = partFile;
// do operations on file
因为PartialFile
扩展File
,你真的不需要'把它变成超类' - 它已经是超类的一个实例。
您可以将PartialFile
对象视为PartialFile
,File
,Object
以及其扩展的任何其他类,同时。您不需要在这些不同的类类型之间进行转换 - 只需直接使用它。对于上面的代码,如果你想调用File.rename()
方法,以下两个语句都会做同样的事情......
partFile.rename();
file.rename();
您无需将partFile
更改为file
以使用File
对象的方法 - 只需直接使用它们,因为Java VM知道PartialFile
1}}也是File
。
您无法真正将子类型更改为其超类型 - Java VM将始终知道它的实际类型 - 但您可以欺骗它。如果您使用以下代码......
PartialFile partFile = new PartialFile();
// do operations on partFile
File file = partFile;
// do operations on file
然后只有每次使用file
而不是partFile
时,您将无法使用任何PartialFile
方法。它有点伪装成PartialFile
,但它实际上并不转换它。
如果你这样做......
public File createFile(){
PartialFile partFile = new PartialFile();
// operations on partFile
return partFile;
}
File file = createFile();
// operations on file
您可以在方法中创建并使用PartialFile
,但是当您完成后,将其作为简单的File
返回。无论何时从现在开始引用此对象,Java VM都会假装它为File
。但是,从技术上讲,它始终是PartialFile
,并且如果您愿意,它不会阻止您将其重新投射到PartialFile
中,就像这样......
PartialFile partFile = (PartialFile)file;
// operations on partFile
所以它只是一种伪装。
答案 2 :(得分:0)
子类已经是它的超类的一个实例,所以你可以把它强制转换为它的超类
class PartialFile extends File {
// Code...
}
PartialFile partialFile;
// Code...
File file = (File) partialFile;
答案 3 :(得分:0)
使用设计模式State和/或Factory方法。
您可能仍需要进行一些重构,因为您很可能需要一个用于超级的接口/抽象基类。
这样的事情:
class MySwitcher implements SuperInterface {
private final SuperInterface super = new Super();
private final SuperInterface subclass = new Subclass();
private SuperInterface current = super; // Start in state "behaves as super"
// Method from SuperInterface
public MyResult doAction(final MyData d) {
final MyResult res = current.doAction(d);
current = setImplementationBasedOnResOfDoAction(res);
return res;
}
}