0

我知道你不能覆盖变量,但是有没有办法基本上“覆盖”下面的最终工作变量?

public class ClassA {
   final protected CustomClass worker;

   public doComplicatedWork() {
        ....
        worker.doSomething();
        ....
   }
}

基本上,我想做的就是扩展CustomClass,并且ClassA像往常一样完成所有工作,除了worker我的扩展CustomClass。两者ClassA和原件CustomClass都在一个罐子里,所以我不想参与修改它们。有没有办法做到这一点?

4

6 回答 6

1

听起来你不需要这样做。大概您将worker作为构造函数参数传递给ClassA,因此只需构造您的工人,并将其传递给ClassA. 您的问题中没有任何内容表明您需要削弱final声明。

于 2013-08-09T15:26:55.993 回答
0

CustomClass如果您的构造函数没有接收worker 作为参数,则可以使用反射来做到这一点。

代码示例:

class ClassA {
    final protected CustomClass worker = null;

    public void doComplicatedWork() {
    }

    public void printWorker(){
        System.out.println(worker); //testing method
    }
}

class CustomClass {
    ...
}

class NewCustomClass extends CustomClass{
    //Your new CustomClass
}

使用反射:

public static void main(String[] args) throws Exception {

    ClassA classA = new ClassA();
    Field f = classA.getClass().getDeclaredField("worker");
    f.setAccessible(true);
    f.set(classA, new NewCustomClass());
    classA.printWorker();
}

它打印:NewCustomClass@19d449fc什么意味着我们覆盖它。

于 2013-08-09T15:13:54.710 回答
0

除了应始终作为最后手段的反射之外,您可以通过巧妙地设计访问器来模拟覆盖该值。IE:

public class SubClass extends ClassA
{
      final protected CustomClass subWorker;

      public CustomClass getWorker()
      {
          return this.subWorker;
      }
}

如果变量仍然存在protected,您就知道用户无法从课堂外访问它。每当他们调用getWorkerfromSubClass时,您已经覆盖了它,它将检索subWorker而不是worker.

于 2013-08-09T15:19:55.067 回答
0

您可以使用反射绕过final

  Field field = ClassA.getField("worker"));
  field.setAccessible(true);
  Field modifiers = Field.class.getDeclaredField("modifiers");
  modifiers .setAccessible(true);
  modifiers .setInt(field, field.getModifiers() & ~Modifier.FINAL);
  field.set(this, newWorker);
于 2013-08-09T15:23:53.437 回答
0

我可能没有正确理解它,但是..你不能扩展ClassA,并用你扩展的工人阶级切换变量工人吗?

public class YourWorkerClass extends CustomClass 
{
     public DoSomething()
     { 
         //yourstuff
     }
}

public class YourClassA extends ClassA
{
    public YourClassA()
    {
        worker = new YourWorkerClass()
    }
}
于 2013-08-09T15:30:09.027 回答
0

您可以扩展 ClassA,但基本上忽略现有的实现并重新实现所有外部,以便您使用您的“工人”等价物。

于 2013-08-09T15:52:22.097 回答