繁体   English   中英

Java多态性和方法链接

[英]Java polymorphism and method chaining

所以我有几个像这样定义的继承类。

class Base {
    public Base chainedMethodA() {
        // some stuff
        return this;
    }
}

class Derived extends Base {
    public Derived chainedMethodB() {
        // some stuff
        return this;
    }
}

现在,以下代码有效:

Derived obj = new Derived();
obj.chainedMethodB().chainedMethodA();

但这不会(注意函数调用的切换顺序):

Derived obj = new Derived();
obj.chainedMethodA().chainedMethodB();

编译器在chainedMethodB()函数调用上给出错误。 我可以理解这是因为当你运行chainedMethodA() ,它返回一个Base类型的对象,它没有定义chainedMethodB

我可以想到这个问题的一些解决方案:

  1. 链式方法同时注意顺序(首先调用Derived的方法,然后调用Base的方法)。 这看起来像一个非常脆弱的解决方案。
  2. Derived覆盖chainedMethodA ,因此它返回Derived而不是Base的实例。 这看起来像是对遗产的浪费。

这个问题有什么优雅的方法吗? 也许某些构造神奇变化chainedMethodA返回一个Derived时类型的对象称为实例Derived ,没有被明确覆盖Derived

Derived覆盖chainedMethodA ,因此它返回Derived而不是Base的实例。 这看起来像是对遗产的浪费。

你错了。 你不是在浪费遗产。

覆盖技术就是做专门的方法。 当返回的类型相同或者在超类中的原始重写方法中声明的返回类型的子类型时,可以执行覆盖。 所以在这种情况下,你什么都没有违反。

请阅读此处了解有关覆盖的更多信息。

这里示例1 :(调用超类方法)

public class Derived extends Base {
    @Override
    public Derived chainedMethodA(){

         super.chainedMethodA();
         //some stuff
        return this;
    }

    public Derived chainedMethodB() {
        // some stuff
        return this;
    }
}

这里的例子2 :(改变它完整)

public class Derived extends Base {
    @Override
    public Derived chainedMethodA(){
        //some stuff
        return this;
    }

    public Derived chainedMethodB() {
        // some stuff
        return this;
    }
    }

在这种情况下,继承可能是最简单的解决方案。

但是,你的最后一句话几乎解释了泛型:

也许某些构造会神奇地更改chainedMethodA,以便在Derived类型的对象调用时返回Derived实例,而不会在Derived中显式覆盖。

所以这样的事情在其他类似的用例中可能会有用:

static class Base {
    public <T extends Base> T chainedMethodA(Class<T> clazz) throws Exception {
        // some stuff
        return clazz.cast(this);
    }
}

static class Derived extends Base {
    public Derived chainedMethodB() {
        // some stuff
        return this;
    }
}

public static void main(String args[]) throws Exception {
    Derived obj = new Derived();
    obj.chainedMethodA(Derived.class).chainedMethodB();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM