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