【问题标题】:Passing Derived Class to a method which needs to override expecting a base class将派生类传递给需要重写期望基类的方法
【发布时间】:2012-03-14 08:12:48
【问题描述】:

我有一个 A 类,有一个抽象方法 doAction(BaseClass obj) 需要一个 BaseClass 类型的参数

public class A {
    //....
    abstract void doAction(BaseClass obj);
    //....
}

现在,我有另一个类 B 需要扩展 A。但是,B 的 doAction 方法需要使用扩展 BaseClass 的对象 DerivedClass。

public class B extends class A {
     //..
     void doAction(DerivedClass obj) {
          obj.callMethodAvailableOnlyInDerivedClass();
      }

 }

如果我需要将 DerivedClass 类型的参数传递给需要 BaseClass 的方法,我该如何处理?

谢谢!

【问题讨论】:

    标签: java inheritance polymorphism


    【解决方案1】:

    你可以使用:

    public abstract class A<T extends BaseClass> {
    //....
    abstract void doAction(T obj);
    //....
    }
    
    
    public class B extends class A<DerivedClass> {
     //..
     void doAction(DerivedClass obj) {
          obj.callMethodAvailableOnlyInDerivedClass();
      }
    
    }
    

    【讨论】:

      【解决方案2】:

      java中没有Contra-Variance的参数,因为它不安全。

      假设你有A a = new B();

      然后你调用a.doAction(new BaseClass())会发生什么?

      这将导致运行时错误,因为B 不知道BaseClass 的“用途”。 java想避免它——所以参数没有协方差。

      【讨论】:

        【解决方案3】:

        你使基类通用:

        public class A<T extends BaseClass> {
            //....
            abstract void doAction(T obj);
            //....
        }
        

        以及用派生类参数化的子类:

        public class B extends A<DerivedClass> {
             //..
             void doAction(DerivedClass obj) {
                 obj.callMethodAvailableOnlyInDerivedClass();
             }
        }
        

        没有泛型,这是不可能的,因为 B 会违反 A 的合同:A 接受任何类型的 BaseClass,但您限制 B 只接受特定的子类。这不尊重Liskov principle

        【讨论】:

        • +1 表示 Liskov 原则。第一次听说,谢谢!
        • 如果你有一堆这样的方法作用于不同的对象?!
        猜你喜欢
        • 1970-01-01
        • 2019-12-24
        • 1970-01-01
        • 1970-01-01
        • 2013-08-02
        • 1970-01-01
        • 2015-08-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多