如果我有这样的类层次结构
AbstractSuperClass
ConcreteClassA
ConcreteClassB
是否可以在AbstractSuperClass
中使用静态方法返回两个具体类之一的类 - 而不是实例 - ?
我尝试过返回Class<AbstractSuperClass>
,但IDE(Android Studio)说
Incompatible types.
Required: Class <com.example.AbstractSuperClass>
Found: Class <com.example.ConcreteClassA>
这是我正在思考的一个例子,但是它无效:
public abstract class AbstractSuperClass{
public abstract void someAbstractMethod();
public static String getSomeText(){
return "This is AbstractSuperClass";
};
public static Class<AbstractSuperClass> getConcreteClass(int x){
switch( x ){
case 0: return ConcreteClassA.class;
case 1: return ConcreteClassB.class;
}
}
}
public class ConcreteClassA extends AbstractSuperClass{
public abstract void someAbstractMethod(){
// Do something
}
public static String getSomeText(){
return "This is ConcreteClassA";
};
}
public class ConcreteClassB extends AbstractSuperClass{
public abstract void someAbstractMethod(){
// Do something
}
public static String getSomeText(){
return "This is ConcreteClassB";
};
}
AbstractSuperClass.getConcreteClass(1).getSomeText(); // Should return "This is ConcreteClassB"
这在Java中根本不可能,或者我只是做错了吗?
答案 0 :(得分:2)
您无法直接从static
调用Class
方法,就像您尝试的那样,您需要反思才能调用getSomeText()
方法。像,
try {
Method m = AbstractSuperClass.getConcreteClass(1).getMethod("getSomeText",
new Class[0]);
System.out.println(m.invoke(null, new Object[0]));
} catch (Exception e) {
e.printStackTrace();
}
然后,您可以使用capture-of extends getConcreteClass
(生产者扩展,消费者超级)修复您的AbstractSuperClass
方法。并且对于没有匹配的情况,您必须具有默认返回。像,
public static Class<? extends AbstractSuperClass> getConcreteClass(int x) {
switch (x) {
case 0: return ConcreteClassA.class;
case 1: return ConcreteClassB.class;
}
return null;
}
我跑了(并得到了)
This is ConcreteClassB
答案 1 :(得分:1)
对于这种方法,
public Class<AbstractSuperClass> getConcreteClass(int x){
switch( x ){
case 0: return ConcreteClassA.class;
case 1: return ConcreteClassB.class;
}
}
签名应为
public Class<? extends AbstractSuperClass> getConcreteClass(int x)
表示返回值可以是AbstractSuperClass.class
或其任何子类型。
答案 2 :(得分:0)
试试这个:
public abstract class AbstractSuperClass {
public abstract void someAbstractMethod();
public static String getSomeText() {
return "This is AbstractSuperClass";
};
public Class<? extends AbstractSuperClass> getConcreteClass() {
return this.getClass();
}
}
实际上你不需要int
参数,因为子类的实例将知道它的类型,而不需要提示。
答案 3 :(得分:0)
我不确定它需要什么,但您的代码中存在几个问题。
您不能直接从类调用any(无关静态或非静态方法)。您需要使用Reflections API,因此方法调用将如下所示:
final class clazz = AbstractSuperClass.getConcreteClass(1); Object result = clazz.getMethod(“getSomeText”)。invoke(clazz);
这就是你上课的完整代码。
package com.mycompany.sandbox;
import java.lang.reflect.InvocationTargetException;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;
abstract class AbstractSuperClass{
public abstract void someAbstractMethod();
public static String getSomeText(){
return "This is AbstractSuperClass";
};
public static Class<? extends AbstractSuperClass> getConcreteClass(int x){
switch( x ){
case 0: return ConcreteClassA.class;
case 1: return ConcreteClassB.class;
}
return null;
}
}
class ConcreteClassA extends AbstractSuperClass{
public void someAbstractMethod(){
// Do something
}
public static String getSomeText(){
return "This is ConcreteClassA";
};
}
class ConcreteClassB extends AbstractSuperClass{
public void someAbstractMethod(){
// Do something
}
public static String getSomeText(){
return "This is ConcreteClassB";
};
}
// one class needs to have a main() method
public class HelloWorld
{
// arguments are passed using the text field below this editor
public static void main(String args[])
{
try {
final Class<? extends AbstractSuperClass> clazz = AbstractSuperClass.getConcreteClass(1);
Object result = clazz.getMethod("getSomeText").invoke(clazz);
System.out.println(Objects.toString(result, "<NULL>"));
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
Logger.getLogger(HelloWorld.class.getName()).log(Level.SEVERE, null, ex);
}
}
}