1
//cls_a is defined by system framework, so we cannot change its definition
public class cls_a {
  public void method_a();
}

//I add a new cls_b implemenation and would like to 
//add a new method_a(int) function
//and prevent client side to access cls_a.method_a()
public class cls_b extends cls_a {
  public void method_a(int a) {
    //do something for a
    method_a();
  }
}

//client side
cls_b b = new cls_b();
b.method_a(2); //it's okay
b.method_a(); //should give something error when compiling code

我想设计cls_b使Java编译器在客户端调用时会出错b.method_a()。任何人都知道如何在Java中做到这一点?

4

6 回答 6

3

我现在要做的是向 method_a() 添加一个 @Deprecated 注释(参见下面的示例),因此客户端会收到警告。由于警告很容易被忽略,有没有办法让编译器出错?

public class cls_b extends cls_a {
  //add @Deprecated 
  @Deprecated @Override public void method_a() {
    super.method_a();
  }
  public void method_a(int a) {
    //do something for a
    method_a();
  }
}

于 2013-01-20T05:20:17.953 回答
2

您不能这样做,因为您不能降低继承方法的可见性(例如,如果它是公共的,则不能将其设为私有)。

为什么不能降低 Java 子类中方法的可见性?解释为什么会这样。

于 2013-01-20T05:11:14.517 回答
2

将其公开后,它的范围就可以在整个项目中使用。没有办法让特定类隐藏公共函数

更新:我刚刚再次阅读了您的问题。我认为您希望其他开发人员在从 b 调用 method_a() 时会遇到异常。如果这是你想要的,那么你可以试试

package com.test;


public class ClassA {
    public static void main (String args[]) {
        ClassB b = new ClassB();
        b.print();
    }
}

class ClassC {
    public void print() {
        System.out.println("printA");
    }
}

class ClassB extends ClassC {

    public void print() {
        try {
            throw new Exception("This method is dead");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void print(int i) {
        System.out.println(i);
    }
}
于 2013-01-20T05:12:23.497 回答
1

您可以这样做:为客户公开一个包装类。

 public class cls_a_Wrapper {
      private cls_a a;

      cls_a_Wrapper(){
          a = new cls_a();
      }  

      //methods
      public void method_a_wrapper(){
           a.method_a();
      }
  }

 public class cls_b extends cls_a_Wrapper {
      public void method_a_wrapper(int a) {

           //delegate to wrapper class method if its allowed
           method_a_wrapper();
     }
  }

所以现在你的客户应该使用 class cls_a_Wrapper class 而不是cls_a

所以现在你可以控制是否要调用基类的公共方法。这是适配器设计模式

如果您不想调用公共方法:

  • 不要在包装类中提供方法。
  • 更改包装类中方法的可见性

请记住:对于客户端原始类不存在。客户端应将包装类视为基类。

于 2013-01-20T05:17:11.880 回答
1

您不能降低方法在子类中的可见性。

JDK 用 UnsupportedOperationException 解决了类似的问题,例如

java.util.Arrays.UnmodifiableCollection

    ...
            public boolean add(E e) {
                throw new UnsupportedOperationException();
            }
    ...

java.util.Collection API 将此类方法标记为optional operation

boolean add(E e) Ensures that this collection contains the specified element (optional operation).
于 2013-01-20T05:47:02.233 回答
0

防止客户端访问基类的公共函数不是一个好的选择。即使您可以提供运行时异常或不推荐使用的方法,客户端也可以按cls_a类型调用您的方法。

cls_a a = new cls_b();
//...
a.method_a();

更好的方法是提供method_a. 对于您的代码,

public class cls_b extends cls_a {
  public void method_a() {
    this.method_a(0);
  }

  public void method_a(int a) {
    //do something for a
    super.method_a();
  }  
}
于 2013-02-05T01:53:28.273 回答