2

私はarraylistsを使用するJavaプログラムを持っています-これらのarraylistsは'variables'を格納します。ここで'variables'は抽象クラスです。

ここで、メモリを節約するために、HugeCollections(VanillaJava)というJavaライブラリを使用したいと思いますが、このライブラリではインターフェイスを定義する必要があります。

抽象クラスをインターフェースに変換するにはどうすればよいですか?変換を正しく実行するには、どのようなルール/制限に従う必要がありますか?

最後に、最小限のコード変更で抽象クラスを使用して、インターフェイスを必要とするライブラリも正しく機能するようにすることは可能ですか?理想的には、抽象クラスをまったく変更したくないのですが...これは可能ですか?

4

3 に答える 3

6

抽象クラスをインターフェースに変換するにはどうすればよいですか?

  1. 抽象クラスのソースファイルのコピーを作成します。

  2. 最初の宣言で「class」を「interface」に変更します。

  3. 名前を変更します(オプションで、何をしているかによって異なります)。

  4. クラスによって実装されているメソッドの本体を削除します。

  5. 他の単語から「abstract」という単語を削除します。

  6. すべてのプライベートメンバーと保護されたメンバーを削除します。

  7. すべてのコンストラクターを削除します。

  8. パブリックメンバーからキーワード「public」を削除します。

削除したコード(実装されたメソッド、プライベートまたは保護されたもの)がある場合は、元の抽象クラスにインターフェイスを実装させ、そのコードをそのままにしておきます。

(不完全)例:

Foo抽象クラスとして:

public abstact class Foo
{
    private int bar;

    public static final int SOME_CONSTANT = 42;

    public Foo(b) {
        this.bar = b;
    }

    public abstract void doSomething(String s);

    protected int doSomethingElse() {
        return this.bar * 2;
    }
}

Fooインターフェイスとして:

public interface Foo
{
    int SOME_CONSTANT = 42;

    void doSomething(String s);
}

私の場合、古いものが持っていたものがあったので、Fooおそらく持っているAbstractFooか何かがあります:

public abstact class AbstractFoo implements Foo
{
    private int bar;

    public Foo(b) {
        this.bar = b;
    }

    public abstract void doSomething(String s);

    protected int doSomethingElse() {
        return this.bar * 2;
    }
}

...実装が必要に応じてそれを開始点として使用できるようにするためです(ただしprivate bar、そこにはそれがありますが、あまり意味がありません)。

于 2012-05-28T15:05:27.027 に答える
3

パターンアダプタが役立つ場合があります。

想像してみてください。SomeClassTargetInterfaceとして使用する必要があります

public abstract class SomeClass {
       // some code here
     public abstract void someMethod();
}

public interface TargetInterface {
     public void someMethodBlaBla();
}

そして、それらはメソッドの異なるシグネチャを持っています-someMethod()someMethodBlaBla()

したがって、このようなアダプタクラスを作成する可能性があります。

public class Adapter implements TargetInterface {
   private SomeClass adaptee;

   public Adapter( SomeClass adaptee ) {
       this.adaptee = adaptee;
   }

   public void someMethodBlaBla() {
       this.adaptee.someMethod();
   }

   //delegate all calls to adaptee
}

そして、コードのどこかで、現在のコードに干渉することなく、アダプターと抽象クラスのインスタンスの両方を使用できます。

SomeClass abstractClassInstance = ... //get instance of your abstract class
TargetInterface targetInterfaceInstance = new Adapter( abstractClassInstance );
于 2012-05-28T15:03:38.203 に答える
0

抽象クラスが具体的なメソッドを定義していない場合は、そのために正規表現を使用することもできます。から:

public abstract class Abstract {
  public abstract void method();
  //...
}

に:

public interface Interface {
  void method();
  //...
}

public abstract修飾子はインターフェースに対して暗黙的です。abstractクラスいくつかのメソッドを定義している場合(すべてのメソッドが定義されているわけではありませんabstract)、またはいくつかのフィールドがある場合、これは(少なくとも簡単に)実行できません。

于 2012-05-28T15:02:56.117 に答える