Java 创建对outerclass的局部变量具有完全访问权限的Innerclass

Java 创建对outerclass的局部变量具有完全访问权限的Innerclass,java,oop,Java,Oop,下面是一个场景 我有一个类a,我希望它的一些方法根据类的调用方式表现出不同的行为 我现在所做的是这样的: interface Interface{ public void someMethod(); } class A{ int variable; Interface getA1(){ return new A1(); } Interface getA2(){ return new A2(); } class A1 extends A impleme

下面是一个场景

我有一个类a,我希望它的一些方法根据类的调用方式表现出不同的行为

我现在所做的是这样的:

interface Interface{
  public void someMethod();
}

class A{
  int variable;
  Interface getA1(){
    return new A1();
  }
  Interface getA2(){
    return new A2();
  }
  class A1 extends A implements Interface{
    public void someMethod(){
       variable++;
    }
  }
  class A2 extends A implements Interface{
    public void someMethod(){
       variable--;
    }
  }
}
现在的问题是,当调用getA1()或getA2()时,它实际上会返回一个全新的A1或A2实例,其中int变量与父类a完全分离(duh,当然这就是它的工作方式)

所以问题是。在java中是否可能返回某种内部类,允许您通过外部类的方法修改外部类中的数据

关键是拥有一个类,该类可以返回以不同方式修改该类的接口,具体取决于创建该接口所使用的方法

我可能忽略了一些简单的事情,对不起,这让我很困惑(

Edit:我认为更好的解释方法是-我想直接访问局部变量、子类(或另一个类),并在原始类中有一个可以创建另一个类的方法。


EDIT2:它在getA1()/getA2()时创建一个单独实例的原因可能是因为类A1和A2被声明为扩展a。似乎如果删除了extends子句,那么它就会按预期工作。

是的,匿名类可以这样做,例如

interface Interface{
  public void someMethod();
}

public class A {
    int variable;

    Interface getA1() {
        return new Interface() {
            @Override
            public void someMethod() {
                variable++;
            }
        };
    }
}
需要指出的是,这相当于声明非静态的内部类,尽管更简洁。

首先,我发现内部类扩展外部类是非常奇怪的。我想不出一个好的理由来这样做,我甚至不确定这样做会起什么作用

除此之外,我不理解您的问题。所有内部类都可以访问其父类的字段。例如,以下内容:

public class Tester {
  private int myInt;

  public InnerTester getInnerTester() {
    return new MyInnerTester();
  }

  public InnerTester getOtherInnerTester() {
    return new OtherInnerTester();
  }

  public interface InnerTester {
    public void doStuff();
  }

  public class MyInnerTester implements InnerTester{
    @Override
    public void doStuff() {
      myInt++;
    }   
  }

  public class MyOtherInnerTester implements InnerTester {
    @Override
    public void doStuff() {
     myInt++;
    }
  }

  public static void main(String[] args) {
    Tester tester = new Tester();
    System.out.println("Before: " + tester.myInt);
    tester.getInnerTester().doStuff();
    tester.getOtherInnerTester().doStuff();
    System.out.println("After: " + tester.myInt);
  }   
}
产出:

Before: 0
After: 2

然而,这一切似乎都很可疑。我不确定你为什么要利用这种行为。我以前也对动作侦听器做过类似的事情,但我不会确切地将它们的父对象称为“ActionListenerFactory”。为什么不使用一个方法来增加对象本身的字段?

除非变量是私有的,否则子类将有权访问它。工厂是否属于基类,这是另一个问题。噢,哇!它成功了!谢谢!我想我忽略了它,因为我认为它与嵌套类的作用相同…Java在m中工作Y严重的方法…应该注意代码不是线程安全的。如果两个不同的线程同时调用getA1().someMethod(),在很短的一段时间内,您无法准确说出哪个值是“变量”将包含。如果您定义一个完整的内部类,这应该完全相同。内部类是匿名的并不意味着它具有“特殊访问权”到其父类的字段。它们完全相同。唯一的区别是内部类是命名的,而匿名类不是。@TimPote我从来没有说过不会。我的回答是“关键是有一个可以返回接口的类…”是的。但你的回答暗示OP对内部类的误解是正确的。“它实际上会返回一个全新的A1或A2实例,其中int变量与父类a完全分离”。这是完全错误的,您的答案根本没有解决这个问题。嘿,Tim,问题是当您实例化一个嵌套类时,它似乎访问了它的outerclass变量的唯一集(我的示例中的did)。草莓发布的方法似乎避免了这种情况。@Liang,这仍然不对。内部类与它们的父实例绑定。无论我创建了多少个内部类实例,它们仍然与我的原始
Tester
实例绑定,并且可以访问他的
myInt
。查看我的编辑以了解我在说什么abo是的,我认为你是对的,我认为这是事实,在我的情况下,我的内部类扩展了外部类,这导致了这种奇怪的行为。干杯