我有以下课程。
public class Super{
public static void useSubClass(){
//I want to access the sub class object here, how.
}
}
public class Sub1 extends Super{
}
public class Sub2 extends Super{
}
我想从超类中的静态方法访问子类对象。即,当我致电Sub1.useSubClass()
时,该方法可以访问Sub1.class
,当我使用Sub2.useSubClass()
时,我可以访问Sub2.class
。
有没有办法从超类访问子类对象。
答案 0 :(得分:4)
一般情况下,你不能从超类中做到这一点(而且不应该!),因为你不会知道(并且不应该假设任何东西!)哪些类将从你的超类继承。
根据您想要做的事情,有其他选择,例如:
更新:正如@JB Nizet指出的那样,我可能误解了这个问题。
如果您希望从超类中的静态方法访问子类,可以执行以下操作(非常类似于Observer Pattern):
List observerList
observerList
super()
,以便将自己注册到observerList
(并在解构器中取消注册)useSubClass()
方法中,您可以遍历该子类实例列表,找到您关心的特定实例(可能由某个参数指定),然后对其执行某些操作。答案 1 :(得分:4)
静态方法不是继承的,调用Sub2.useSubClass()
完全等同于调用Super.useSubclass()
。
无法获取此信息,因为它不存在。编译器允许调用Sub2.useSubclass()
,但将其转换为Super.useSubclass()
。
答案 2 :(得分:1)
public static void useSubClass(Super sub) {
if (sub instanceof Sub1) {
// Do something
} else if (sub instanceof Sub2) {
// Do something else
} else {
// Something else is extending Super
}
}
然而,更好的问题是为什么?你不能简单地覆盖你的子类中的方法吗?
答案 3 :(得分:0)
不,你不能因为超类不能知道子类的方法。 您应该考虑创建一个新类,它既可以看到超类,也可以在这个新类中实现静态方法
答案 4 :(得分:0)
对于记录,您可以使用类方法在Python中执行此操作:
class super(object):
@classmethod
def usesubclass(cls):
print cls
class sub1(super):
pass
class sub2(super):
pass
使用此代码,您可以致电sub1.usesubclass()
或sub2.usesubclass()
,这将分别打印sub1
和sub2
类的表示形式:
>>> sub1.usesubclass()
<class '__main__.sub1'>
>>> sub2.usesubclass()
<class '__main__.sub2'>
但是,不幸的是,Java并不支持这种机制。在您的示例中编译Sub1.useSubClass()
时,编译器将仅使用Sub1
作为基本命名空间来查找useSubClass()
中的Super
方法,但没有相关信息。实际上编译成代码。在生成的字节码中,调用只是直接调用Super.useSubClass()
而不再是。
我同情你的困境,但Java就是这样。我认为,你最接近的是以下代码:
public class Super {
public static <T extends Super> void useSubClass(Class<T> sub) {
}
}
然后将该方法明确地称为Super.useSubClass(Sub1.class)
或Super.useSubClass(Sub2.class)
。
答案 5 :(得分:0)
我想出了什么。如果小心实施,它就可以工作。
/** SuperClass.java **/
public abstract class SuperClass {
public static void printClass(){
System.out.println(new ImplementingClassRetriever().getCallingClass());
}
static class ImplementingClassRetriever extends SecurityManager{
public Class getCallingClass() {
Class[] classes = getClassContext();
for (Class clazz : classes) {
if (SuperClass.class.isAssignableFrom(clazz) && clazz != null
&& !clazz.equals(SuperClass.class)) {
return clazz;
}
}
return null;
}
}
}
/** Main.java **/
public class Main{
public static void main(String[] args) {
Sub.printClass(); //this does not work
Sub.testStaticCall(); //this works!! :)
}
}
class Sub extends SuperClass{
public static void testStaticCall(){
Sub.printClass(); //calling the method in the super class
}
}
这只是一个玩具的例子。超类包含一个静态类,它包含一个检索调用类的方法。
在子类中,我有另一个静态方法,它调用超类的方法来打印类名。
Main
类/函数包含对Sub
的继承和本地实现方法的两次调用。第一个调用打印为null,因为调用上下文(即Main)不是Super
的子类但是Sub
中的委托方法有效,因为调用上下文现在是SuperClass
的子类因此可以确定通话类。
答案 6 :(得分:-2)
虽然您可以创建对超类的引用并将其指向任何子类。这也可以在运行时动态完成。这是运行时多态性的一种方式。