有 Java 编程相关的问题?

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

Java中的OOP:带方法链的类继承

我有一个父类,它定义了链表方法(返回“this”的方法)的集合。我想定义多个子类,这些子类包含它们自己的链表方法,但也“覆盖”父类方法,以便返回子类的实例而不是父类

我不想在每个子类中重复相同的方法,这就是为什么我有一个包含所有子类共享的方法的父类。谢谢

class Chain {
  public Chain foo(String s){
    ...
    return this;
  }
}

class ChainChild extends Chain {
  //I don't want to add a "foo" method to each child class
  /*
  public ChildChain foo(String s){
    ...
    return this;
  }
  */

  public ChainChild bar(boolean b){
    ...
    return this;
  }
}

ChainChild child = new ChainChild();
child.foo().bar(); //compile error: foo() returns a "Chain" object which does not define the bar() method. 

共 (4) 个答案

  1. # 1 楼答案

    我已经根据您的需要使用泛型编写了这个示例

    class Parent {
        public <T extends Parent> T foo() {
            return (T)this;
        }
    }
    
    class Child extends Parent {
    
    }
    
    class AnotherChild extends Parent {
    
    }
    
    public class Test {
        public static void main(String[] args) {
    
            Parent p = new Child();
            System.out.println(p);
            Child c = p.foo();
            System.out.println(c);
            //throws ClassCastException here since Child is not AnotherChild
            AnotherChild ac = p.foo();
            System.out.println(ac);
        }
    }
    
  2. # 2 楼答案

    父类中返回this的方法仍将返回对子类对象的引用。您只能将其视为父类的对象(除非强制转换),但它实际上是其原始类型

    你可以考虑使用这样的泛型:

    // This seems a bit too contrived for my liking. Perhaps someone else will have a better idea.
    public class Parent<T extends Parent<T>> {
        T foo () {
            return (T) this;
        }
    }
    
    public class Child extends Parent<Child> {
        public void bar () {
            Child c = foo();
        }
    }
    
  3. # 3 楼答案

    你可以直接投

    ChainChild child = new ChainChild();
    ((ChainChild) child.foo()).bar();
    

    你可以试试:

    public ? extends Chain foo() {
        return this;
    }
    

    但我不确定这是否有帮助,即使它可以编译

  4. # 4 楼答案

    以下是对OldCurmudgeon方法的改进:

    public class Parent<This extends Parent<This>> {
    
        @SuppressWarnings("unchecked")
        private final This THIS = (This)this;
    
        public This foo() {
            //...
            return THIS;
        }
    
        public This bar() {
            //...
            return THIS;
        }    
    }
    
    public class Child extends Parent<Child> {
    
        // you can override super with covariant return type
        @Override
        public Child bar() {
            super.bar();
    
            return this;
        }
    }
    
    
    Child child = 
    new Child()
    .foo()
    .bar();
    

    改进是只进行一次未检查的强制转换,并将其保存为常量THIS,您可以将其作为方法链接的返回值重用

    这将删除每个方法中未检查的强制类型转换,并使代码更清晰

    您可以通过返回子对象而不是此(协变返回类型)来重写父对象的方法