有没有一种设计模式,我可以让一个对象具有某种状态,他从一个扩展对象开始,但一段时间后又回到它的超级对象。
例如 - 部分文件继承自文件,完成后它将成为一个文件。
有没有一种设计模式,我可以让一个对象具有某种状态,他从一个扩展对象开始,但一段时间后又回到它的超级对象。
例如 - 部分文件继承自文件,完成后它将成为一个文件。
不,Java 中没有类型突变(公平地说,我想不出任何现代语言都有它)。
你可以做什么,但显然不完全相同:
new Float(new Double(2));
)。请注意,这不会更改初始对象,因此您必须再次分配持有它的变量。type
基于 的变量,enum
指示对象的性质。对于大多数目的来说,这就足够了(并且可以让您免于构建繁重的类型层次结构)。现在,您需要类型突变吗?如果您只需要处理您的对象,就好像它是其超类的直接实例一样,您已经可以做到了。类型突变的主要区别在于您调用了被覆盖的方法,但如果类型层次结构设计正确,这通常很好。
假设我要设计一个 PartialFile 类(假设名称正确定义了它是什么),而不是使用继承,我会使用 composition :我会创建一个装饰类,其实例将有一个 variable private File sourceFile
。
这个问题是有缺陷的 - 扩展Object
始终是其超类的实例。
在您的示例中,以下是有效的......
public class PartialFile extends File{
// methods
}
PartialFile partFile = new PartialFile();
// do operations on partFile
File file = partFile;
// do operations on file
因为PartialFile
extends File
,你真的不需要“把它变成它的超类”——它已经是超类的一个实例。
您可以同时将PartialFile
对象视为 a PartialFile
、 a File
、 anObject
以及它扩展的任何其他类。您无需在这些不同的类类型之间转换它 - 直接使用它即可。对于上面的代码,如果你想调用File.rename()
方法,下面的两个语句都会做同样的事情......
partFile.rename();
file.rename();
您无需将partFile
a 更改为file
使用File
对象的方法 - 只需直接使用它们,因为 Java VM 知道 aPartialFile
也是 a File
。
您不能真正将子类型更改为它的超类型——Java VM 将始终知道它真正是什么类型——但你可以欺骗它。如果您使用以下代码...
PartialFile partFile = new PartialFile();
// do operations on partFile
File file = partFile;
// do operations on file
然后只有每次使用file
而不是partFile
,您将无法使用任何PartialFile
方法。它有点伪装它 a PartialFile
,但它实际上并没有转换它。
如果你做这样的事情......
public File createFile(){
PartialFile partFile = new PartialFile();
// operations on partFile
return partFile;
}
File file = createFile();
// operations on file
您可以在方法中创建和使用 a PartialFile
,但完成后将其作为简单的File
. 从现在开始,每当你引用这个对象时,Java VM 都会假装它是一个File
. 但是,从技术上讲,它始终是 a ,并且如果您愿意,PartialFile
它不会阻止您将其转换回 a ,就像这样......PartialFile
PartialFile partFile = (PartialFile)file;
// operations on partFile
所以这只是一个伪装。
使用设计模式状态和/或工厂方法。
您可能仍然需要进行一些重构,因为您很可能需要超级接口/抽象基类。
像这样的东西:
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;
}
}
一个子类已经是它的超类的一个实例,所以你可以把它转换成它的超类
class PartialFile extends File {
// Code...
}
PartialFile partialFile;
// Code...
File file = (File) partialFile;