Java:如何使用超类设计集合

Java:如何使用超类设计集合,java,inheritance,collections,reference,Java,Inheritance,Collections,Reference,这是一个实际的问题,但我不确定是否有实际的答案。如果你有一个超类,比如说有10个子类,那么把这10个子类放到一个集合中最简单的方法是什么?现在(这可能是一个糟糕的设计),我已经将它们放在超类的静态集合字段中 然而,这个问题的动机是因为我获得了其中一个子类的一个字段的标识,但我需要引用同一个子类中的另一个字段 例如,假设子类具有以下字段: public class SampleSubClass extends SampleSuperClass{ ... private Object1 o_1; p

这是一个实际的问题,但我不确定是否有实际的答案。如果你有一个超类,比如说有10个子类,那么把这10个子类放到一个集合中最简单的方法是什么?现在(这可能是一个糟糕的设计),我已经将它们放在超类的静态集合字段中

然而,这个问题的动机是因为我获得了其中一个子类的一个字段的标识,但我需要引用同一个子类中的另一个字段

例如,假设子类具有以下字段:

public class SampleSubClass extends SampleSuperClass{
...
private Object1 o_1;
private Object2 o_2;
private Object3 o_3;
...
}
在程序的其他地方,我只有o_2的身份,我想得到o_3。 理论上,有一种方法可能比将SampleClass的所有实例放在某个集合中更简单。例如,也许在我的梦中,有一种软件语言存在,其中超类确实包含关于其子类的信息,而超类本身就是一个集合

但别担心。现在对我来说,将集合放在程序中某个地方似乎是一个好方法,即使用hashmap/hashtable,并将其用作超类的静态成员

请告诉我有更好的办法。有没有办法通过只引用对象中的字段B来引用对象中的字段A


例如,假设我有一个ActionPerformed方法,它有一个包含在ActionEvent对象参数中的源对象。如何找到拥有/包含该源对象的类的实例?设计这个的最佳方法是什么?

回答您的直接问题:如何轻松定义包含给定类集的集合

public class ClassA {
    private final List<Class<? extends a>> knownSubclasses = Arrays.asList(ClassB.class, ClassC.class);
};
class ClassB extends ClassA {}
class ClassC extends ClassA {}
可能通过使用接口识别具有object3的实例

public interface MyClassWithObject3 { Object3 getObject3(); }

...
void someOperation(SomeSuperclass that) {
   if (that instanceof MyClassWithObject3) { ... }
}
您还可以使用命名属性

void someOperation(SomeSuperClass that) {
    Object3 object3 = that.getProperty("object3");
}

给定字段引用的对象,没有本机方法来查找字段的所有者。JVM记录指向每个对象的引用的数量,这样就可以进行垃圾收集,但它不跟踪引用的所有者

您可以将所有字段的值存储在映射到其所有者的
映射中:

import java.util.*;

public class Super
{
    static Map<Object, Super> owners = new IdentityHashMap<Object, Super>();
    // IdentityHashMap will not work with primitives due to autoboxing,
    // but HashMap requires all field values to have sensible implementations
    // of hashCode() and equals().

    /** Gets the owner associated with a field. */
    public static Object getOwner(Object field)
    {
        return owners.get(field);
    }

    /** Establishes ownership over a field. */
    protected void own(Object field)
    {
        owners.put(field, this);
    }

    /** Removes an ownership, but only if this is the owner. */
    protected void disown(Object field)
    {
        if (owners.get(field) == this) owners.remove(field);
    }

    /** Shorthand for disown(oldField); own(newField). */
    protected <T> T change(T oldField, T newField)
    {
        disown(oldField);
        own(newField);
        return newField;
    }
}

public class SubA extends Super
{
    protected String s;
    protected Integer i;

    public SubA(String aString, Integer anInt) { setS(aString); setI(anInt); }
    public void setS(String aString) { s = change(s, aString); }
    public void setI(Integer anInt) { i = change(i, anInt); }
    public String toString() { return "SubA(" + s + "," + i + ")"; }
}

public class SubB extends Super
{
    protected Object o;

    public SubB(Object anObject) { setO(anObject); }
    public void setO(Object anObject) { o = change(o, anObject); }
    public String toString() { return "SubB(" + o + ")"; }
}

public class Demo
{
    public static void main(String[] args)
    {
        String s1 = "String1", s2 = "String2", s3 = "String3";
        Integer i1 = 111, i2 = 222;
        Object o1 = new Object(), o2 = new Object();

        SubA a1 = new SubA(s1, i1), a2 = new SubA(s2, i2);
        SubB b = new SubB(o1);

        p("s1 owner = %s", Super.getOwner(s1)); // SubA(String1,111)
        p("s2 owner = %s", Super.getOwner(s2)); // SubB(String2,222)
        p("s3 owner = %s", Super.getOwner(s3)); // null
        p("i1 owner = %s", Super.getOwner(i1)); // SubA(String1,111)
        p("i2 owner = %s", Super.getOwner(i2)); // SubA(String2,222)
        p("o1 owner = %s", Super.getOwner(o1)); // SubB(java.lang.Object@...)
        p("o2 owner = %s", Super.getOwner(o2)); // null

        p("s1 -> s3, o1 -> o2");
        a1.setS(s3);
        b.setO(o2);

        p("s1 owner = %s", Super.getOwner(s1)); // null
        p("s3 owner = %s", Super.getOwner(s3)); // SubA(String3,111)
        p("o1 owner = %s", Super.getOwner(o1)); // null
        p("o2 owner = %s", Super.getOwner(o2)); // SubB(java.lang.Object@...)
    }

    static void p(String fmt, Object... args)
    {
        System.out.format(fmt, args);
        System.out.println();
    }
}
import java.util.*;
公共级超级
{
静态映射所有者=新标识hashmap();
//由于自动装箱,IdentityHashMap无法与原语一起工作,
//但是HashMap要求所有字段值都有合理的实现
//hashCode()和equals()的函数。
/**获取与字段关联的所有者*/
公共静态对象getOwner(对象字段)
{
返回所有者。获取(字段);
}
/**建立对字段的所有权*/
受保护的void own(对象字段)
{
所有者。放置(字段,此);
}
/**删除所有权,但仅当该所有权是所有者时*/
受保护的无效拒绝(对象字段)
{
如果(owners.get(field)=此)owners.remove(field);
}
/**否认(旧域)的简写;拥有(新域)*/
受保护的T更改(T旧字段,T新字段)
{
否认(奥德菲尔德);
own(纽菲尔德);
返回newField;
}
}
公共类SubA扩展超级
{
受保护字符串s;
受保护整数i;
公共SubA(字符串aString,整数anInt){setS(aString);setI(anInt);}
公共void集(字符串aString){s=change(s,aString);}
公共空集合i(整数anInt){i=change(i,anInt);}
公共字符串toString(){return“SubA(“+s+”,“+i+”);}
}
公共类SubB扩展了Super
{
保护对象o;
公共子B(对象对象){setO(对象);}
public void setO(Object anObject){o=change(o,anObject);}
公共字符串toString(){return“SubB(“+o+”);}
}
公开课演示
{
公共静态void main(字符串[]args)
{
字符串s1=“String1”,s2=“String2”,s3=“String3”;
整数i1=111,i2=222;
对象o1=新对象(),o2=新对象();
SubA a1=新SubA(s1,i1),a2=新SubA(s2,i2);
SubB=新的SubB(o1);
p(“s1所有者=%s”,Super.getOwner(s1));//SubA(string1111)
p(“s2所有者=%s”,Super.getOwner(s2));//SubB(string2222)
p(“s3所有者=%s”,Super.getOwner(s3));//null
p(“i1所有者=%s”,Super.getOwner(i1));//SubA(string1111)
p(“i2所有者=%s”,Super.getOwner(i2));//SubA(string2222)
p(“o1所有者=%s”,Super.getOwner(o1));//SubB(java.lang)。Object@...)
p(“o2所有者=%s”,Super.getOwner(o2));//null
p(“s1->s3,o1->o2”);
a1.套(s3);
b、 setO(o2);
p(“s1所有者=%s”,Super.getOwner(s1));//null
p(“s3所有者=%s”,Super.getOwner(s3));//SubA(string3111)
p(“o1所有者=%s”,Super.getOwner(o1));//null
p(“o2所有者=%s”,Super.getOwner(o2));//SubB(java.lang。Object@...)
}
静态void p(字符串fmt、对象…args)
{
系统输出格式(fmt,args);
System.out.println();
}
}
或者,您可以通过继承或使用包装类,使字段值本身维护对其所有者的引用:

public class OwnableObject
{
    protected Object owner;

    public OwnableObject(Object anOwner) { owner = anOwner; }
    public Object getOwner() { return owner; }
    public void setOwner(Object anOwner) { owner = anOwner; }
}

public class MyString extends OwnableObject
{
    protected String str = null;

    public MyString(Object anOwner) { super(anOwner); }
    public String toString() { return str; }
    public void set(String aString) { str = aString; }
}

public class FieldWrapper<E> extends OwnableObject
{
    protected E value = null;

    public FieldWrapper(Object anOwner) { super(anOwner); }
    public E getValue() { return value; }
    public void setValue(E aValue) { value = aValue; }
}

public class Demo
{
    protected MyString s = new MyString(this);
    protected FieldWrapper<Integer> i = new FieldWrapper<Integer>(this);

    public void setS(String aString) { s.set(aString); }
    public void setI(int anInt) { i.setValue(anInt); }
    public String toString() { return "Demo(" + s + "," + i.getValue() + ")"; }

    public static void main(String[] args)
    {
        Demo d1 = new Demo();
        Demo d2 = new Demo();

        MyString f1 = d1.s;
        FieldWrapper<Integer> f2 = d1.i;
        OwnableObject f3 = d2.s;
        OwnableObject f4 = d2.i;

        d1.setS("one");
        d2.setS("two");
        d1.setI(1000);
        d2.setI(2000);

        p("f1 = %s, owner = %s", f1, f1.getOwner());
        p("f2 = %d, owner = %s", f2.getValue(), f2.getOwner());
        p("f3 = %s, owner = %s", f3, f3.getOwner());
        p("f4 = %s, owner = %s", f4, f4.getOwner());
    }

    static void p(String fmt, Object... args)
    {
        System.out.format(fmt, args);
        System.out.println();
    }
}
公共类OwnableObject
{
保护对象所有者;
public-owneableobject(Object-anOwner){owner=anOwner;}
公共对象getOwner(){return owner;}
public void setOwner(Object anOwner){owner=anOwner;}
}
公共类MyString扩展了OwnableObject
{
受保护字符串str=null;
public MyString(Object anOwner){super(anOwner);}
公共字符串toString(){return str;}
公共void集(字符串aString){str=aString;}
}
公共类FieldWrapper扩展了OwnableObject
{
受保护的E值=空;
公共字段包装器(对象anOwner){super(anOwner);}
public E getValue(){return value;}
public void setValue(E aValue){value=aValue;}
}
公开课演示
{
受保护的MyString s=新MyString(此);
受保护的FieldWrapper i=新的FieldWrapper(此);
public class OwnableObject
{
    protected Object owner;

    public OwnableObject(Object anOwner) { owner = anOwner; }
    public Object getOwner() { return owner; }
    public void setOwner(Object anOwner) { owner = anOwner; }
}

public class MyString extends OwnableObject
{
    protected String str = null;

    public MyString(Object anOwner) { super(anOwner); }
    public String toString() { return str; }
    public void set(String aString) { str = aString; }
}

public class FieldWrapper<E> extends OwnableObject
{
    protected E value = null;

    public FieldWrapper(Object anOwner) { super(anOwner); }
    public E getValue() { return value; }
    public void setValue(E aValue) { value = aValue; }
}

public class Demo
{
    protected MyString s = new MyString(this);
    protected FieldWrapper<Integer> i = new FieldWrapper<Integer>(this);

    public void setS(String aString) { s.set(aString); }
    public void setI(int anInt) { i.setValue(anInt); }
    public String toString() { return "Demo(" + s + "," + i.getValue() + ")"; }

    public static void main(String[] args)
    {
        Demo d1 = new Demo();
        Demo d2 = new Demo();

        MyString f1 = d1.s;
        FieldWrapper<Integer> f2 = d1.i;
        OwnableObject f3 = d2.s;
        OwnableObject f4 = d2.i;

        d1.setS("one");
        d2.setS("two");
        d1.setI(1000);
        d2.setI(2000);

        p("f1 = %s, owner = %s", f1, f1.getOwner());
        p("f2 = %d, owner = %s", f2.getValue(), f2.getOwner());
        p("f3 = %s, owner = %s", f3, f3.getOwner());
        p("f4 = %s, owner = %s", f4, f4.getOwner());
    }

    static void p(String fmt, Object... args)
    {
        System.out.format(fmt, args);
        System.out.println();
    }
}