首页 > 解决方案 > Java 泛型,返回类型以仅访问抽象类型的受保护方法

问题描述

我的应用程序中有以下设置

//Package 1
public class class1 extends AbstractClass2<class1>{

  public void someMethod(){
    // What i want here is when i call the method "with", I should be able to chain only 
    // the methods defined in AbstractClass3 and not the methods defined in its sub classes.
    with(10).someOtherMethod() // this should be possible (it is possible with the current setup)
    with(10).someMethod() // this should not be possible (it is possible with the current setup)
  }

}

//Package 2
public abstract class AbstractClass2<T> extends AbstractClass3<T>{
  protected void someMethod(){
  }
}

public abstract class AbstractClass3<T>{

  protected T with(int value){
    setValue(value);
    return (T) this;
  }

  protected void someOtherMethod(){
  }

}

基本上我试图实现方法链接,但将其限制在基类“AbstractClass3”中定义的方法。我应该如何实现这一目标?

标签: javagenericsreturn-type

解决方案


问题出在with(int value)和中someOtherMethod()。而且您也不需要泛型AbstractClass3(至少在您提供的示例中)。

你的“with”方法应该是protected AbstractClass3 with(int value). 请注意,该方法现在返回 a AbstractClass3,这意味着只有在此类中定义的方法才可用(除非您将其强制转换为子类)。

最后,方法可见性有一个吸引人的技巧,someOtherMethod()它应该是公共的。如果您在不同的包中,则只能通过this.引用调用受保护的方法(当然是通过继承)。

我认为在带有注释的代码中更好地解释:

public abstract class AbstractClass3 {

    protected AbstractClass3 with(int value) {
        // Do stuff.
        return this;
    }

    // If "someOtherMethod()" is protected, you will only be able to call
    // it from sub-classes using "this." reference if you are in a different package.
    // So, we make it public.
    public void someOtherMethod() {
    }

}

public abstract class AbstractClass2<T> extends AbstractClass3 {
    protected void someMethod() {
    }
}

public class Class1 extends AbstractClass2<ANY_CLASS_HERE> {

    public void someMethod() {
        // If someOtherMethod() is protected, this will NOT work because you are not calling it
        // through "this." reference. YOU CAN ONLY CALL PROTECTED METHODS THROUGH "this." reference
        // IF YOU ARE IN A DIFFERENT PACKAGE. As you are calling someOtherMethod() from another 
        // instance returned by "with(10)", that means that you are calling it "outside"; 
        // the "this." reference is "inside" the instance returned by "with(10)". In order for 
        // it to work, someOtherMethod() must be public (or be in the same package).
        // Remember: You need "this." reference to call protected methods in different packages.
        with(10).someOtherMethod();

        // If someOtherMethod() is protected, this works because you are calling
        // it through "this." reference. It's a straight call to the parent.
        this.someOtherMethod(); // Note the "this." reference.

        // ERROR because someMethod() does not exists in AbstractClass3 and "with(10)".
        // returns an AbstractClass3 instance.
        with(10).someMethod();
    }

}

我取出了仿制药,AbstractClass3但你可以随时取回它。这里重要的是你明白你的“with”方法应该返回,并且如果你在不同的包中,AbstractClass3只能通过引用调用受保护的方法。this.


推荐阅读