オブジェクトを拡張オブジェクトとして開始するある種の状態にすることができるデザインパターンはありますが、しばらくするとそのスーパーに戻ります。
たとえば、部分的なファイルはファイルから継承され、完成後はファイルになります。
オブジェクトを拡張オブジェクトとして開始するある種の状態にすることができるデザインパターンはありますが、しばらくするとそのスーパーに戻ります。
たとえば、部分的なファイルはファイルから継承され、完成後はファイルになります。
いいえ、Java には型の突然変異はありません (そして、公平を期すために、現代の言語でそれを持っているとは考えられません)。
あなたができることですが、明らかにまったく同じではありません:
new Float(new Double(2));
)。これは初期オブジェクトを変更しないため、それを保持する変数を再度割り当てる必要があることに注意してください。type
に基づいてenum
、オブジェクトの性質を示す変数を追加します。ほとんどの場合、これで十分です (そして、重い型階層を構築する必要がなくなります)。さて、あなたは型の突然変異が必要ですか?オブジェクトをそのスーパークラスの直接のインスタンスであるかのように処理する必要がある場合は、既にそれを行うことができます。型の変更との主な違いは、オーバーライドされたメソッドを呼び出すことですが、型の階層が正しく設計されていれば通常は問題ありません。
そして、継承を使用する代わりに (名前がそれが何であるかを適切に定義すると仮定して) PartialFile クラスを設計すると仮定すると、合成を使用したことになります: インスタンスが 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
オブジェクトが拡張するその他のクラスであると考えることができます。これらの異なるクラス タイプ間で切り替える必要はありません。直接使用するだけです。上記のコードの場合、メソッドを呼び出したい場合、次のステートメントは両方とも同じことを行います...PartialFile
File
Object
File.rename()
partFile.rename();
file.rename();
オブジェクトのメソッドを使用するためpartFile
に を aに変更する必要はありません。Java VMは a も であることを認識しているため、直接使用するだけです。file
File
PartialFile
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
だからただの変装です。
サブクラスはすでにそのスーパークラスのインスタンスであるため、そのスーパークラスにキャストするだけです
class PartialFile extends File {
// Code...
}
PartialFile partialFile;
// Code...
File file = (File) partialFile;
設計パターン 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;
}
}