簡體   English   中英

Java從父對象調用子方法

[英]Java invoke child method from parent object

我有下一種情況:

有一個抽象類

public abstract class SuperClass {
    public abstract void getString();
    public abstract void method2();
}

public class InheritClass1 extends SuperClass {
    @Override
    public void getString(){...};
    @Override
    public void method2(){...};
}

public class InheritClass2 extends SuperClass {
    @Override
    public void getString{...};
    @Override
    public void method2(){...};

    public void customMethod(){...};
}

還有另一個類,該類的方法接受SuperClass對象作為參數。 根據getString返回的字符串類型,我執行不同的操作。 我的情況是我試圖在對象屬於父類時調用子方法:

public class Processor {
    public String method(SuperClass type) {
         switch (type.getString()) {
             case "1":
               return "OK"
             case "2":
               return ((InheritClass2) type).customMethod()
         }
 }

我確實知道這是錯誤的設計,請您幫我找到解決該問題的最佳方法。 也許泛型在某種程度上適合這種情況。 還有一點是,customMethod()應​​該不是所有類的一部分。

根據您的設計,您可以應用:

if (type instanceof InheritClass2.class) return type.customMethod();

要么

if (type.getClass() == InheritClass2.class) return type.customMethod();

由於只有一些(子)類實現customMethod ,所以我建議創建一個包含此方法的接口:

public interface CustomInterface {
    public String customMethod();
}

這樣,您的SuperClass可以保持原樣。 然后,只有具有customMethod的子類/子類才可以擴展您的SuperClass並實現此CustomInterface 這樣,未實現CustomMethod的子類(它們的類中沒有方法,例如您的示例中的InheritClass1 )也將保持原樣。

然后,只有具有CustomMethod子類(例如InheritClass2才需要稍作更改,方法是說它實現了這個新接口:

public class InheritClass2 extends SuperClass implements CustomInteface {
    // the rest stays the same
}

然后,在您要進行轉換的部分中,您需要執行以下操作:

public class Processor {
    public String method(SuperClass type) {
        switch (type.getString()) {
            case "1":
                return "OK"
            case "2":
                String s = "";
                if (type instance of CustomInterface) {
                    s = (CustomInterface type).customMethod();
                }
                return s;
        }
    }
}

以這種方式使用接口將有助於您實現所有子類,而不僅是實現CustomInterface子類,因此,所有子類都可以使用instanceof並強制轉換為接口來調用customMethod() -您不會必須分別處理需要此方法的每個孩子。


注意:您的代碼是經過簡化的示例,尚不清楚getString()方法是否只是返回子類的標識符,以便讓您知道可以強制轉換的子類,然后在...上調用自定義方法。 switch和getString方法的目的-確定哪些類型實現了customMethod()並調用該方法,對於沒有該方法的任何子類僅返回“ OK”-那么您可以執行以下操作:

public class SubClass1 extends SuperClass implements CustomInterface {
    // other mehtods...
    public String CustomMethod() { return "SomeString1"; }
}

public class SubClass2 extends SuperClass {
    // other methods...
    // this subclass does not have the CustomMethod()
}

public class SubClass3 extends SuperClass implements CustomInterface {
    // other methods...
    public String CustomMethod() { return "SomeString3"; }
}

然后,您的處理器可能如下所示:

public class Processor {
    public String method(SuperClass type) {
        return (type instanceof CustomInterface) ? ((CustomInterface) type).CustomMethod() : "OK";
    }

    public static void main(String[] args) {
        Processor p = new Processor();
        SuperClass obj1 = new SubClass1();
        SuperClass obj2 = new SubClass2();
        SuperClass obj3 = new SubClass3();

        System.out.println(p.method(obj1)); // prints: "SomeString1"
        System.out.println(p.method(obj2)); // prints: "OK"
        System.out.println(p.method(obj3)); // prints: "SomeString3"
    }
}

如果您不了解三元運算符,則可以在此處閱讀有關內容這是condition ? exprTrue : exprFalse condition ? exprTrue : exprFalse語法。 基本上,這是一個簡短的if else語句。

您可以使用默認的自定義方法實現創建一個接口,例如:

interface A {
    default String customMethod() {
        return "";
    }
}

抽象類將實現此接口:

public abstract class SupperClass implements A {
    public abstract String getString();
    public abstract void method2();
}

錯誤的設計會導致您獲得錯誤的答案。 如果您不想將對象強制轉換為子對象。 您可以使用反射。

import java.lang.reflect.Method;

public class Processor {
    public String method(SuperClass type) {
        Method[] methods = type.getClass().getMethods();
        for (Method m : methods) {
            if (m.getName().equals("customMethod")) {
                try {
                    return m.invoke(type);
                } catch (Exception ex) {
                    // throw
                } 
            }
        }
        return "OK";
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM