Java 扩展第三方类的困难

Java 扩展第三方类的困难,java,inheritance,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 +

我有以下课程

         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新对象时,1

它创建了一个类型为B的对象,其名称为new object,值为1。并在调用print方法时打印相同的内容。但是,尽管它有这些值,我不能通过B的方法访问它们。这是封装还是继承的限制

因为同样的情况摆在我面前,我需要扩展一个第三方类和这个类中的属性,这些属性是私有的,但在扩展类中是必需的,私有成员没有setter和getter。
那么我必须做什么呢?

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


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

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


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

如果变量是私有的,那么它们就是私有的-类的设计者决定不需要它们

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

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

如果变量是私有的,那么它们应该是私有的——类的设计者已经决定不需要它们

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

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

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


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

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


如果没有,其他答案是合适的。

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

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

我假设您需要扩展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,因为还有其他东西需要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);
      }

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

谢谢,但我知道,我想了解更多关于如何进行的信息。谢谢,但我知道,我想了解更多关于如何操作的信息。你能给出字段classjava.lang.reflect.Field的fqn吗?从getDeclaredField返回的内容可以看出。你能给出字段classjava.lang.reflect.Field的fqn吗?从getDeclaredField返回的内容可以看出OP表明父类是第三方的。也就是说,他或她无法控制它的设计,大概无法修改它。@Matthew Flynn:我知道。然而,这可能会导致他们重新考虑使用设计糟糕的第三方软件包的决定。此外,他们还提供了超类的源代码,尽管这可能只是一个示例——很难从英语中分辨出来。我对此没有异议。很可能第三方类编写得很糟糕,不建议使用它。另一方面,可能已经存在对该类的依赖,因此删除该类会再次造成过度破坏,因为设计不佳。毕竟,大多数系统都实现了泥球模式。OP指出父类是第三方的。也就是说,他或她无法控制它的设计,大概无法修改它。@Matthew Flynn:我知道。然而,这可能会导致他们重新考虑使用设计糟糕的第三方软件包的决定。此外,他们还提供了超类的源代码,尽管这可能只是一个示例——很难从英语中分辨出来。我对此没有异议。很可能第三方类编写得很糟糕,不建议使用它。另一方面,可能已经存在对该类的依赖,因此删除该类会再次造成过度破坏,因为设计不佳。毕竟,大多数系统都采用泥球模式。