代码之家  ›  专栏  ›  技术社区  ›  GuruKulki

扩展第三方类的难度

  •  1
  • GuruKulki  · 技术社区  · 15 年前

    我有下列课程

             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类型的对象,名称=新对象,值=1。并在调用print()方法时打印。但是,尽管它包含这些值,但我不能通过B的方法访问它们。它是封装或继承的限制吗?

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

    5 回复  |  直到 15 年前
        1
  •  3
  •   Bozho    15 年前

    如果变量是 private ,它们本来就是这样的-类的设计者已经决定不需要它们。

    但是,该类的设计器可能是错误的。首先,这不是一个好的假设,但是如果你真的需要它们,你可以打电话给:

    Field field = getClass().getSuperclass().getDeclaredField("privateFieldName");
    field.setAccessible(true);
    Object value = field.get(this);
    
        2
  •  1
  •   Randy Simon    15 年前

    如果变量是私有的,那么就不能在定义它们的类之外访问它们。

    通过将这些字段分配给类B的构造函数中的字段,可以在A中隐藏这些字段。但是,如果A中的值发生了变化,您将不知道B类中的这些变化,反之亦然。

        3
  •  1
  •   Matthew Flynn    15 年前

    我假设您需要扩展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)则是完全隐藏和不相关的。您还将代码与第三方代码分开,这意味着您可以更轻松地处理第三方的更新和升级。

        4
  •  0
  •   Steve Emmerson    15 年前

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

    否则,其他的答案是合适的。

        5
  •  0
  •   sateesh    15 年前

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