简体   繁体   English

如何指定抽象类方法的返回类型

[英]How to specify the return type of the method of an abstract class

I found a lot of post on the subject, but couldn't manage to find the solution I was looking for. 我发现了很多关于这个主题的帖子,但无法找到我想要的解决方案。

So here is the deal: 所以这里是交易:

I have a first abstract class with two subclasses: 我有一个带有两个子类的第一个抽象类:

public abstract class A {
  public A(args){..}
}
public class B extends A {
  public B(args){
    super(args);
  }
}
public class C extends A{
  public C(args){
    super(args);
  }
}

args is some variables but doesn't change in form. args是一些变量但不会改变形式。 Some other stuff are in the classes, but it doesn't matter here. 其他一些东西都在课堂上,但这并不重要。

Now, I have another abstract class with two subclasses that are builders for B and C. The most part of the builders is the same, so I'd like it to be in the abstract builder 现在,我有另一个带有两个子类的抽象类,它们是B和C的构建器。构建器的大部分是相同的,所以我希望它在抽象构建器中

public abstract class Builder {
  public A build(*?*){
    //compute args
    return new *either B or C*(args);
  }
}
public class B_Builder extends Builder {
  public B build(*?*){
    super(*?*);
  }
}
public class C_Builder extends Builder{
  public C build(*?*){
    super(*?*);
  }
}

Once again, the other stuff in the builders doesn't really matter. 再一次,建设者中的其他东西并不重要。

My question is how to tell to the Builder abastract class what the return type of build should be through the builders subclass. 我的问题是如何通过构建器子类告诉Builder abastract类构建的返回类型。 Knowing that the return type B and C both extends A. I guess I should use some generic stuff, but I can't manage to make it work. 知道返回类型B和C都扩展了A.我想我应该使用一些通用的东西,但我无法使其工作。

Can anyone help me ? 谁能帮我 ?

Thanks a lot ! 非常感谢 !

LD LD

You can do it with a generic type parameter and an abstract creator method that does the construction while the abstract class does the heavy lifting: 你可以使用泛型类型参数和抽象创建器方法来完成构建,而抽象类可以完成繁重的工作:

public abstract class Builder<T extends A> {
  public T build(*?*){
    //compute args
    return create(args);
  }

  protected abstract T create(args);
}

public class B_Builder extends Builder<B> {
  @Override
  protected B create(args) {
    return new B(args);
  }
}

public class C_Builder extends Builder<C>{
  @Override
  protected C create(args) {
    return new C(args);
  }
}

Yes you are close enough, generic is the way to go: 是的,你足够接近,通用是要走的路:

A: A:

public abstract class A <T extends A<?>>{

    public abstract T getObject(Object args);
}

B: B:

   public class B extends A<B>{

        @Override
        public B getObject(Object args) {
            // TODO Auto-generated method stub
            return null;
        }

    }

C: C:

public class C extends A<C>{

    @Override
    public C getObject(Object args) {
        // TODO Auto-generated method stub
        return null;
    }


}

Add a template parameter to the super class Builder. 将模板参数添加到超类构建器。

class Builder<T> {
  T build() {}
}

Then when you extend use something like 然后,当你扩展使用类似的东西

   class ABuilder extends Builder<A> {
      A build() {}
    }

   class BBuilder extends Builder<B> {
      B build() {}
    }

Full code with a working example in Codiva online compiler IDE . 完整代码与Codiva在线编译器IDE中的工作示例。

I will suggest put the same part to a single method, and the create codes of B and C should be in the sub-builders. 我建议将相同的部分放在一个方法中,B和C的创建代码应该在子构建器中。

public abstract class Builder<T> {
  public abstract T create(args);
  public void build(args){
    //do something here
    return create(args); 
  }
}
public class BBuilder extends Builder<B> {
  @Override
  public B create(int args) {
    return new B(args);
  }
}

You can leave only one builder with a single build method like this: 您只能使用一个构建方法保留一个构建器,如下所示:

public class BuilderA {
public static <T extends A> T of(Class<T> type, Object arg) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
    Constructor<T> constructor = type.getConstructor(arg.getClass());
    return constructor.newInstance(arg);
}
}

This method uses reflection to build an instance with the specified type. 此方法使用反射来构建具有指定类型的实例。 It assumes that the same type of parameter is used in the constructor of classes A, B and C. Here is how a call would look like: 它假定在​​类A,B和C的构造函数中使用相同类型的参数。以下是调用的外观:

    A a1 = BuilderA.of(B.class, 1);        
    A a2 = BuilderA.of(C.class, 2);
    B b = BuilderA.of(B.class, 2);
    C c = BuilderA.of(C.class, 2);

In the above calls, all the classes have a constructor with the type Integer. 在上面的调用中,所有类都有一个Integer类型的构造函数。 If you have multiple arguments, you can use varargs as the last parameter and retrieve the classes of the vararg and use them for retrieving the right constructor. 如果您有多个参数,则可以使用varargs作为最后一个参数并检索vararg的类并使用它们来检索正确的构造函数。

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

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