1

既存のクラスのサブクラスを作成する必要があります。これは、その方法を知っていますが、スーパークラスを変更せずに、既存のスーパークラスに基づいてサブクラスを作成できる必要があります。

例えば:

public class Foo
{
    public Foo(int a)
    {
        _a = a;
    }
    private int _a;
}
public class Bar extends Foo
{
    public Bar(int a, int b)
    {
        super(a);
        _b = b;
    }
    public Bar(Foo foo, int b)
    {
        ???? //<----What do I do here?
        _b = b;
    }
    private int _b;
}
public static class Baz
{
    static void Main(String[] args)
    {
        Foo foo = new Foo(1);
        Bar bar = new Bar(foo, 2); //<---- How do I set this up?
    }
}

したがって、上記の例では、Fooの既存のインスタンスを使用して、それをBarに変換し、_bフィールドを2に設定します。

編集

重要な制約、私は誰もがFooを編集するように私に言うとは思いませんでした。Fooを変更することはできません。そのクラスは編集できないライブラリにあるため、Fooを編集せずに実行する必要があります。

EDIT2

これが実際のFooで、MinecraftのChunkProviderクラスです。

public class ChunkProvider
    implements IChunkProvider
{

    public ChunkProvider(World world, IChunkLoader ichunkloader, IChunkProvider ichunkprovider)
    {
        chunkSet = new HashSet();
        chunkMap = new HashMap();
        chunkList = new ArrayList();
        field_28064_b = new EmptyChunk(world, new byte[32768], 0, 0);
        field_28066_g = world;
        field_28069_d = ichunkloader;
        field_28070_c = ichunkprovider;
    }

    //(Snip) There are no GetXXX members for the below fields.

   private Set chunkSet;
    private Chunk field_28064_b;
    private IChunkProvider field_28070_c;
    private IChunkLoader field_28069_d;
    private Map chunkMap;
    private List chunkList;
    private World field_28066_g;

}
4

6 に答える 6

3

これを回避する方法があり、それは継承するのではなくFoo、それを構成してそのメソッドに委任することです。

「本物」Fooがインターフェースを実装していることに気づきました。Fooコンクリートではなく、そのインターフェイスを中心にコードを設計できる場合は、次のBarようになります。

public class Bar implements IFoo {
  public Bar(IFoo foo, ...) {
    _foo = foo;
  }
  private IFoo _foo;
  // implement IFoo delegating all calls to _foo...
}
于 2011-06-24T21:38:42.603 に答える
2

Foo のプライベート変数 _a にアクセサー メソッドがなく、Foo を変更できない場合、リフレクションを除いて、説明したことを行う方法はありません。単純に Foo._a へのアクセス権がありません。

于 2011-06-24T21:24:18.340 に答える
1

を繰り返しFoo.class.getDeclaredFields()、名前を持つものを探し_aます。Field.setAccessible(true)フィールドを呼び出すと、Field.getValue()必要な値が得られます。

このより一般的なコードを保持します

@SuppressWarnings("unchecked")
public static <T> T getFieldValue(Object target, String name) throws NoSuchFieldException, IllegalAccessException {
    Class<? extends Object> c = target.getClass();
    Field field = findField(c, name);
    if (field == null)
        throw new NoSuchFieldException(name);
    field.setAccessible(true);
    return (T) field.get(target);
}

public static Field findField(Class<? extends Object> clas, String name) {
    if (clas == null)
        return null;
    Field[] declaredFields = clas.getDeclaredFields();
    for (Field field : declaredFields) {
        if (field.getName().equals(name))
            return field;
    }
    return findField(clas.getSuperclass(), name);
}

そのような不測の事態のために横たわっています。

于 2011-06-24T21:26:36.590 に答える
0

電話するだけ

super(foo.getA()) // assuming you have a getA method

あなたの疑問符はどこにありますか。

新しい Bar インスタンスを foo にすることはできません。(できれば、今日は間違いなく何かを学んだでしょう)。

于 2011-06-24T21:09:59.303 に答える
0

を引数としてFoo取り、 のコピーを作成するコンストラクターを追加し、指定した場所でそのコンストラクターを呼び出します。Foo_a

編集:

public class Bar extends Foo
{
    public Bar(int a, int b)
    {
        super(a);
        _b = b;
    }
    public Bar(Foo foo, int b)
    {
        super(foo.getA(),b);  <------
        _b = b;
    }
    private int _b;
}
于 2011-06-24T21:10:12.673 に答える
0

Foo のソースがある場合は、フィールドなどにアクセスするために必要なメソッドを追加してコピーし、コピーを元のクラスパスの前に配置します。

于 2011-06-24T21:33:50.683 に答える