[英]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.