扩展第三方课程的难度

时间:2010-02-16 17:36:03

标签: java inheritance

我有以下课程

         class A{
          private String name;
          private int value;

           public A(String n, int v){
           name = n;
           value = v;
           }

           public void print(){
           System.out.println(name + " " + value);
           }
          }



           class B extends A{
            public B(String n, int v){
              super(n,v);
            }
           }

当我说B b =新B(“新对象”,1);

它创建了一个B类型的对象,其名称= new object和value = 1.并在调用print()方法时打印相同的对象。但是虽然它有这些值,但我无法通过B的方法访问它们。是封装还是继承的限制。

因为在我面前有同样的情况,我需要扩展第三方类,并且这个类中的属性是私有的,但在扩展类中是必需的,并且私有成员没有setter和getter 。 那我该怎么办?

5 个答案:

答案 0 :(得分:3)

如果变量是private,那么它们就是这样 - 班级设计师决定不需要它们。

然而,该班的设计师可能错了。首先假设这不是一件好事,但如果你真的需要它们,你可以打电话:

Field field = getClass().getSuperclass().getDeclaredField("privateFieldName");
field.setAccessible(true);
Object value = field.get(this);

答案 1 :(得分:1)

如果变量是私有的,那么您无法在定义它们的类之外访问它们。

您可以通过将它们分配给B类构造函数中的字段来遮蔽A中的这些字段。但是,如果在A中更改了值,则您将不知道B类中的这些更改,反之亦然。

答案 2 :(得分:1)

我假设您需要扩展A,因为还有其他东西需要A并且您希望能够替换子类型吗?

我还假设您有源代码A,正如您在上面显示的那样?

一个解决方案(不是一个很好的解决方案,因为你在处理升级到第三方类时会遇到问题,但可能是可行的):

将整个A源复制到新文件B中。

将类定义和构造函数更改为:

public class B extends A {
  private String name;
  private int value;

  public B(String n, int v){
    name = n;
    value = v;
  }

现在你有了一个子类来覆盖父类的每个方法(代码完全相同)。

根据需要修改B.

或者,更好的是,使B中的实例变量受到保护,然后创建第三个扩展B的子类C,并将更改放入:

    public class B extends A {
      protected String name;
      protected int value;

      public B(String n, int v){
        name = n;
        value = v;
      }

      ...
    }

    public class C extends B {

      public C ( String n, int v) {
        super(n, v);
      }

现在您的子类可以直接访问父实例变量,而祖父母的(A)完全隐藏且不相关。您还将代码与第三方代码分开,这意味着您可以更轻松地处理第三方的更新和升级。

答案 3 :(得分:0)

如果子类中确实需要私有成员,那么您的问题表明超类的设计很差。必须仔细设计可继承的类(因为“A”是因为它没有“最终”限定符),以避免出现问题,例如您遇到的问题。最好的解决方案是重写A类以更好地支持继承。

如果不这样做,其他答案都是合适的。

答案 4 :(得分:0)

可能是第三方课程没有按设计提供任何getter / setter。重新审视扩展课程的需要。而不是扩展类可以通过使用组合而不是继承来实现您想要的东西吗? 是否存在第三方类实现的接口,检查是否可以使用Decorator模式实现您的要求。