简体   繁体   English

Java从父对象调用子方法

[英]Java invoke child method from parent object

I've got next situation: 我有下一种情况:

There is an abstract class 有一个抽象类

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(){...};
}

There is another class that has a method that accepts SuperClass object as an argument. 还有另一个类,该类的方法接受SuperClass对象作为参数。 Depending on what kind of String is returned from getString I perform different actions. 根据getString返回的字符串类型,我执行不同的操作。 My case is that I am trying to call a child method while the object is of parent class: 我的情况是我试图在对象属于父类时调用子方法:

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

I do understand that this is BAD DESIGN, could you please help me with finding the best solution for this problem. 我确实知道这是错误的设计,请您帮我找到解决该问题的最佳方法。 Maybe generics are suitable in this case somehow. 也许泛型在某种程度上适合这种情况。 Also the thing is that customMethod() should be a part of not all classes. 还有一点是,customMethod()应​​该不是所有类的一部分。

Depending on your design you could apply: 根据您的设计,您可以应用:

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

or 要么

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

Since only some (sub)classes implements customMethod , I would suggest to create an interface that contains this method: 由于只有一些(子)类实现customMethod ,所以我建议创建一个包含此方法的接口:

public interface CustomInterface {
    public String customMethod();
}

Your SuperClass can then remain just as it is. 这样,您的SuperClass可以保持原样。 Only the subclasses/child classes that have customMethod , would then extend your SuperClass as well as implement this CustomInterface . 然后,只有具有customMethod的子类/子类才可以扩展您的SuperClass并实现此CustomInterface This way, the child classes that do not implement CustomMethod (does not have the method in their class, such as InheritClass1 in your example), also remain just as they are. 这样,未实现CustomMethod的子类(它们的类中没有方法,例如您的示例中的InheritClass1 )也将保持原样。

Only child classes that have CustomMethod , such as InheritClass2 would then need to change slightly by saying it implements this new interface: 然后,只有具有CustomMethod子类(例如InheritClass2才需要稍作更改,方法是说它实现了这个新接口:

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

Then in the section where you want to do the casting, you rather do the following: 然后,在您要进行转换的部分中,您需要执行以下操作:

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;
        }
    }
}

Using the interface in this way will help that you can implement all child classes and not just one as implementing the CustomInterface , and thus, all child classes will work with using instanceof and casting to the interface to call customMethod() - you won't have to handle each child that needs this method separately. 以这种方式使用接口将有助于您实现所有子类,而不仅是实现CustomInterface子类,因此,所有子类都可以使用instanceof并强制转换为接口来调用customMethod() -您不会必须分别处理需要此方法的每个孩子。


NOTE: Your code is clearly simplified example, it is unclear if the getString() method is just returning an identifier of the child classes in order for you to know which ones you can cast and then call custom Method on... If this is the purpose of your switch and getString methods - to identify which types implement the customMethod() and to call that method, and for any child class that does not have that method to return just "OK" - then you could instead do the following: 注意:您的代码是经过简化的示例,尚不清楚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"; }
}

Then your Processor could look like this: 然后,您的处理器可能如下所示:

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"
    }
}

If you don't understand the ternary operator then you can read about it here That's the condition ? exprTrue : exprFalse 如果您不了解三元运算符,则可以在此处阅读有关内容这是condition ? exprTrue : exprFalse condition ? exprTrue : exprFalse syntax. condition ? exprTrue : exprFalse语法。 It's a short if else statement basically. 基本上,这是一个简短的if else语句。

You can create an interface, with default custom method implementation, like: 您可以使用默认的自定义方法实现创建一个接口,例如:

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

And abstract class will implement this interface: 抽象类将实现此接口:

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

Bad design will cause you to get bad answers. 错误的设计会导致您获得错误的答案。 If you don't want to cast your object to a child object. 如果您不想将对象强制转换为子对象。 You could use reflection. 您可以使用反射。

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