繁体   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