[英]Return a class, not an instance, of a concrete class that extends an abstract base class?
如果我有这样的班级层次结构
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中根本不可能吗,还是我做错了?
您不能像尝试那样直接从Class
调用static
方法,您将需要进行反射才能调用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();
}
然后,可以使用捕获的扩展AbstractSuperClass
(生产者扩展,消费者超级)来修复getConcreteClass
方法。 如果没有匹配项,则必须具有默认返回值。 喜欢,
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
对于这种方法,
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
或其任何子类型。
尝试这个:
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
参数,因为子类的实例无需提示即可知道其类型。
我不确定它需要什么,但是您的代码中有几个问题。
您不能直接从类中调用any(无关紧要的静态方法或非静态方法)。 您需要使用反射API,因此您的方法调用将如下所示:
final class clazz = AbstractSuperClass.getConcreteClass(1); 对象结果= 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);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.