扩展类中的ClassName.this

时间:2018-04-04 05:55:54

标签: java inheritance scope

我继承了一些代码,我试图重构它以试图清理它。

这是我收到代码的简化案例:

public class Foo
{
   private void doSomething()
   {
       someOtherAction(Foo.this);
   }
   protected class FooChildClass
   {
        protected void anotherAction()
        {
             createDialogBox(Foo.this);
        }
   }
}
//totally not related to class Foo even though most code is duplicated
public class Bar
{
   private void doSomething()
   {
       someOtherAction(Bar.this);
   }
   protected class BarChildClass
   {
        protected void anotherAction()
        {
             createDialogBox(Bar.this);
        }
   }
}

现在,这里有一个问题 - 在进一步检查代码之后, Bar 几乎是 Foo 的副本,并且在这里和那里稍作改动。

我想将我的代码压缩成这样的东西:

//superclass
public class Foo
{
   protected void doSomething()
   {
       someOtherAction(Foo.this);
   }
   protected class ChildClass
   {
        protected void anotherAction()
        {
             createDialogBox(Foo.this);
        }
   }
}
//inherits from Foo and only overrides when necessary
public class Bar extends Foo
{
   //rely on base implementation of doSomething
   //override other functions only when necessary
}

我的压缩代码会成功运行吗?我有一个C#背景,所以我理解了很多Java语法,但C#与 ClassName.this 没有任何相似之处。

我认为 ClassName.this 旨在通过定义'this'的目的来解决范围问题 - 而且使用我修改后的代码, Bar 确实是一个 Foo 对象 - 但我想我会要求确定!

编辑原始问题以澄清

2 个答案:

答案 0 :(得分:3)

参考您最近的编辑,我编写了以下示例:

public class Foo {
    public void printMe() {
        System.out.println("I'm foo");
    }

    public class Child {
        public void printMe() {
            Foo.this.printMe();
        }
    }
}

public class Bar extends Foo {
    @Override
    public void printMe() {
        System.out.println("I'm bar");
    }
}

public class Main {
    public static void main(String[] args) {
        new Bar().new Child().printMe();
    }
}

结果是:

I'm bar

总结一下,Foo.this.printMe() 静态引用外部类Foo,而{{1>}引用外部实例实例,在本例中是Child的实例。

进一步阅读:

Bar语法用于内部类。

您可以使用以下示例尝试一下并查看其效果:

Classname.this

关于派生,没有办法在java中显式引用某个超类型,比如在C中。但是,你可以使用public class Foo { private int value = 1; public class Bar { private int value = 2; public void printValue() { System.out.println(Foo.this.value); } } } 关键字引用你的超类。

使用java 1.8和默认接口方法,引入了super语法:

Classname.super

但是,您仍然只能引用直接超类型。编译器将拒绝其他所有内容。

答案 1 :(得分:3)

Foo.this相当于this。因此,您的压缩代码是正常的,无需更改。

以下测试代码是测试您更新的程序:

    Foo f = new Foo();
    Foo.ChildClass fc = f.new ChildClass();
    f.doSomething();
    fc.anotherAction();

    Bar b = new Bar();
    Bar.ChildClass bc = b.new ChildClass();
    b.doSomething();
    bc.anotherAction();

输出结果为:

Foo@52e922
Foo@52e922
Bar@25154f
Bar@25154f