【问题标题】:Is it possible to override the argument type of an overridden method?是否可以覆盖被覆盖方法的参数类型?
【发布时间】:2019-04-02 11:55:31
【问题描述】:

有人可以帮我写下面的代码吗?

我有 2 个类 Controller1Controller2 实现接口控制器如下:

package com.controllers
public interface Controllers{
    public void method1(*****);
}
------------------------------
package com.controllers
public class Controller1{
    public void method1(com.model1.Module1 module);
}
------------------------------
package com.controllers
public class Controller2{
    public void method1(com.model2.Module1 module);
}
------------------------------

我有 2 个包,它们具有相同的类(两个类也具有相同的方法),如下所示

package com.model1
public class Module1{

}
------------------------
package com.model1
public class Module2{

}
-----------------------
package com.model2
public class Module1{

}
------------------------
package com.model2
public class Module2{

}

我使用工厂类在运行时获取Controller1Controller2 的实例,因此继承类中method1 的参数类型会有所不同。但我不能这样做,因为方法签名不能被覆盖。

有人可以给我推荐一个替代方案吗?谢谢...

【问题讨论】:

标签: java inheritance polymorphism overriding


【解决方案1】:

我有 2 个具有相同类的包(两个类也具有相同的方法)

那为什么没有为 Module1、Module2 创建公共父接口呢?

看起来像

package com.model1
public class Module1 implements Model {

}
------------------------
package com.model1
public class Module2 implements Model{

}
-----------------------
package com.model2
public class Module1 implements Model{

}
------------------------
package com.model2
public class Module2 implements Model{

}

package com.controllers
public interface Controllers{
    public void method1(Model model);
}

但我可能错过了你的问题

【讨论】:

  • Module1 和 Module2 有不同的方法。我想创建一个单一的界面不是一个好主意。
【解决方案2】:

无论如何,如果您不想使用 Module1 或 Module2 方法,您可以创建一个名为 Method 的空接口,这将是一个解决方案。如果你想使用他们的方法,你可以做同样的事情并添加类似的东西(阅读 Java 中的反射)

package com.controllers
public interface Controllers{
    public void method1(Model model) {
        if (model instanceof com.model1.Module1) {
            com.model1.Module1 module = (com.model1.Module1) model;
            ...
        } else if (model instanceof com.model2.Module1) {
            com.model2.Module1 module = (com.model2.Module1) model;
            ...
        }
    }
}

【讨论】:

    【解决方案3】:

    你为什么不使用一些泛型?

    像这样:

    public class Example {
    
        public static void main(String[] args) {
    
            Object module = new Random().nextBoolean()? new Module2(): new Module1();
            Factory factory = new Factory();
            Controllers produce1 = factory.produce(module.getClass());
            produce1.method1(module);
    
        }
    }
    
    class Factory {
    
        Controllers produce(Class<?> clz) {
            if (Module1.class.equals(clz)) return new Controller1();
            if (Module2.class.equals(clz)) return new Controller2();
            throw new IllegalArgumentException();
        }
    
    }
    
    interface Controllers<T> {
        void method1(T t);
    }
    
    class Controller1 implements Controllers<Module1> {
    
        public void method1(Module1 integer) {
            System.out.println("in 1!");
        }
    }
    
    class Controller2 implements Controllers<Module2> {
    
        public void method1(Module2 module) {
            System.out.println("in 2!");
        }
    }
    
    
    class Module1 {
    
    }
    
    class Module2 {
    
    }
    

    【讨论】:

    • Module1 和 Module2 有不同的方法。因此,最好为所有包中的每个模块创建单独的接口(如果是这样,我将不得不创建 9 个接口)。
    • 另外,对象produce1将被动态初始化。在这种情况下,如何声明引用变量?谢谢
    • 更新了我的例子,你需要改变方法produce(Class&lt;?&gt; clz)的参数,你可以在运行时做任何你想做的事情。
    猜你喜欢
    • 1970-01-01
    • 2021-05-24
    • 1970-01-01
    • 2012-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多