有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

泛型Java从父对象调用子方法

我有下一个情况:

有一个抽象类

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

还有一个类有一个接受超类对象作为参数的方法。根据getString返回的字符串类型,我会执行不同的操作。我的情况是,当对象是父类时,我试图调用子方法:

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

我知道这是个糟糕的设计,你能帮我找到解决这个问题的最佳方案吗。也许在这种情况下,仿制药是合适的。还有一点是customMethod()不应该是所有类的一部分


共 (4) 个答案

  1. # 1 楼答案

    由于只有一些(子)类实现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"
        }
    }
    

    如果你不理解三元运算符,那么你可以阅读here这就是condition ? exprTrue : exprFalse语法。这基本上是一个简短的if-else语句

  2. # 2 楼答案

    您可以创建一个带有默认自定义方法实现的接口,如:

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

    抽象类将实现这个接口:

    public abstract class SupperClass implements A {
        public abstract String getString();
        public abstract void method2();
    }
    
  3. # 3 楼答案

    糟糕的设计会让你得到糟糕的答案。如果不想将对象强制转换为子对象。你可以使用反射

    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";
        }
    }
    
  4. # 4 楼答案

    根据您的设计,您可以应用:

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

    或者

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