1

オブジェクトを拡張オブジェクトとして開始するある種の状態にすることができるデザインパターンはありますが、しばらくするとそのスーパーに戻ります。

たとえば、部分的なファイルはファイルから継承され、完成後はファイルになります。

4

4 に答える 4

2

いいえ、Java には型の突然変異はありません (そして、公平を期すために、現代の言語でそれを持っているとは考えられません)。

あなたができることですが、明らかにまったく同じではありません:

  • オブジェクトをパラメーターとして受け取るコンストラクターを使用して、別のクラスで新しいオブジェクトを構築します (できるようにnew Float(new Double(2));)。これは初期オブジェクトを変更しないため、それを保持する変数を再度割り当てる必要があることに注意してください。
  • typeに基づいてenum、オブジェクトの性質を示す変数を追加します。ほとんどの場合、これで十分です (そして、重い型階層を構築する必要がなくなります)。

さて、あなたは型の突然変異が必要ですか?オブジェクトをそのスーパークラスの直接のインスタンスであるかのように処理する必要がある場合は、既にそれを行うことができます。型の変更との主な違いは、オーバーライドされたメソッドを呼び出すことですが、型の階層が正しく設計されていれば通常は問題ありません。

そして、継承を使用する代わりに (名前がそれが何であるかを適切に定義すると仮定して) PartialFile クラスを設計すると仮定すると、合成を使用したことになります: インスタンスが variable を持つ装飾クラスを作成したことになりますprivate File sourceFile

于 2012-11-13T12:17:54.960 に答える
1

この質問には欠陥があります。拡張Objectは常にそのスーパー クラスのインスタンスです。

あなたの例では、以下が有効です...

public class PartialFile extends File{
    // methods
    }

PartialFile partFile = new PartialFile();

// do operations on partFile 

File file = partFile;

// do operations on file

PartialFileextendsであるためFile、「それをスーパー クラスに変換する」必要はありません。すでにスーパー クラスのインスタンスになっています。

オブジェクトは、、 、 、およびPartialFileオブジェクトが拡張するその他のクラスであると考えることができます。これらの異なるクラス タイプ間で切り替える必要はありません。直接使用するだけです。上記のコードの場合、メソッドを呼び出したい場合、次のステートメントは両方とも同じことを行います...PartialFileFileObjectFile.rename()

partFile.rename();
file.rename();

オブジェクトのメソッドを使用するためpartFileに を aに変更する必要はありません。Java VMは a も であることを認識しているため、直接使用するだけです。fileFilePartialFileFile

サブタイプをそのスーパー タイプに実際に変更することはできません。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

だからただの変装です。

于 2012-11-13T12:18:33.573 に答える
0

サブクラスはすでにそのスーパークラスのインスタンスであるため、そのスーパークラスにキャストするだけです

class PartialFile extends File {
// Code...
}

PartialFile partialFile;
// Code...
File file = (File) partialFile;
于 2012-11-13T12:18:15.290 に答える
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;
  }

}
于 2012-11-14T07:33:48.347 に答える