简体   繁体   English

外部与超级课程

[英]Outer vs. Super class

Does super has higher priority than outer class? 超级比外级更优先吗?

Consider we have three classes: 考虑我们有三个类:

  1. ClassA ClassA的
  2. ClassB ClassB的
  3. Anonymous class in ClassB that extends ClassA ClassB中的匿名类,它扩展了ClassA

ClassA.java: ClassA.java:

public class ClassA {
    protected String var = "A Var";

    public void foo() {
        System.out.println("A foo()");
    }
}

ClassB.java: ClassB.java:

public class ClassB {
    private String var = "B Var";

    public void test() {

        new ClassA() {
            public void test() {
                foo();
                System.out.println(var);
            }
        }.test();
    }

    public void foo() {
        System.out.println("B foo()");
    }
}

When I call new ClassB().test() , I get the following output (which is pretty much expected): 当我调用new ClassB().test() ,我得到以下输出(这是非常期待的):

A foo()
A Var

Question: Is it defined somewhere that inner class takes (methods and members) first from the super class and then from the outer class or is it JVM compiler implementation dependent? 问题:它是在某个地方定义的,内部类首先从超类中获取(方法和成员),然后从外部类中获取,还是依赖于 JVM 编译器实现? I have looked over the JLS(§15.12.3) but couldn't find any reference for that, maybe it is pointed out there but I misunderstood some of the terms? 我查看了JLS(§15.12.3),但找不到任何参考,也许有人指出,但我误解了一些条款?

See 6.3.1 Shadowing Declarations : 请参见6.3.1影子声明

A declaration d of a method named n shadows the declarations of any other methods named n that are in an enclosing scope at the point where d occurs throughout the scope of d . 名为N法的声明d 阴影名为N的任何其它方法,这些方法在这里d发生在整个d的范围的点的封闭的范围的声明

Which may be interpreted as "the declaration of foo (inherited from ClassA ) shadows the declaration of any other methods named foo that are in an enclosing scope ( ClassB ) at the point where foo occurs, throughout the scope of foo ." 可能被解释为“ foo的声明(继承自ClassA )在foo整个范围内影响foo发生点处的封闭范围( ClassB )中名为foo的任何其他方法的声明。”

Also relevant - section 15.12.1 : 也相关 - 第15.12.1节:

15.12.1 Compile-Time Step 1: Determine Class or Interface to Search 15.12.1编译时步骤1:确定要搜索的类或接口

The first step in processing a method invocation at compile time is to figure out the name of the method to be invoked and which class or interface to check for definitions of methods of that name. 在编译时处理方法调用的第一步是确定要调用的方法的名称以及检查该名称的方法定义的类或接口。 There are several cases to consider, depending on the form that precedes the left parenthesis, as follows: 有几种情况需要考虑,具体取决于左括号前面的形式,如下所示:

  • If the form is MethodName , then there are three subcases: 如果表单是MethodName ,则有三个子句:
    • If it is a simple name, that is, just an Identifier , then the name of the method is the Identifier. 如果它是一个简单的名称,即只是一个标识符 ,那么该方法的名称就是标识符。 If the Identifier appears within the scope (§6.3) of a visible method declaration with that name, then there must be an enclosing type declaration of which that method is a member. 如果标识符出现在具有该名称的可见方法声明的范围(第6.3节)中,则必须存在该方法所属的封闭类型声明。 Let T be the innermost such type declaration. 设T是最里面的类型声明。 The class or interface to search is T . 要搜索的类或接口是T.
    • If it is a qualified name of the form TypeName.Identifier, then [...] 如果它是TypeName.Identifier形式的限定名称,那么[...]
    • In all other cases, the qualified name has the form FieldName.Identifier; 在所有其他情况下,限定名称的格式为FieldName.Identifier; then [...] 然后 [...]

I think you are always going to get "A var" . 我想你总会得到"A var"

This is because your test() method implementation is being defined on an anonymous subclass of A . 这是因为您的test()方法实现是在A的匿名子类上定义A I don't think you can access the B.var instance variable within your test() method unless you explicitly refer to the outer class using ClassB.this.var . 我不认为您可以在test()方法中访问B.var实例变量,除非您使用ClassB.this.var显式引用外部类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM