2017-07-18 45 views
4

我正在学习Java中的内部和外部类。我知道内部和外部类是什么以及为什么使用它们。我在这个话题上遇到了以下问题,但找不到答案。如何定义继承内部类的子类的构造函数?

假设下面的代码给出:

class outer{ 
    class inner{ 

    } 
} 

class SubClass extends outer.inner{ 
} 

问:应该如何最小的子类构造函数中定义?为什么?

Option 1- 
Subclass() { 
    //reason: bacause the default constructor must always be provided 
} 
Option 2- 
Subclass (Outer outer) { 
    //reason : because creating an instance of **Subclass** requires an instance 
    //of outer, which the **Subclass** instance will be bound to 
} 

Option 3- 
Subclass (Outer outer) { 
    outer.super(); 
    //reason : because creating an instance of **Subclass** requires an explicit 
    //call to the **Outer's** constructor, in order to have an enclosing instance 
    //of **Outer** in scope. 
} 
Option 4- 
Subclass (Outer.inner inner) { 
    //reason : bacause an instance of **inner** is necessary so that there is a 
    //source to copy the derived properties from 
} 

PS。这是一个多选题。只有1回答预计

我是新来的Java,不知道太多关于这些高级的主题

感谢

+0

相信没有以上的,并认为这是对一个[接收机参数的情况下 - JLS# 8.4.1](http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.1)。 – EJP

回答

2

下面是从遵循这个相同的逻辑,而是由不流通的JLS为例但通过直接在构造函数中创建实例:

示例8.8.7.1-1。合格的超类构造函数调用

class Outer { 
    class Inner {} 
} 
class ChildOfInner extends Outer.Inner { 
    ChildOfInner() { (new Outer()).super(); } 
} 

父类的构造调用可细分为:

  • 不合格的父类的构造调用开头的关键字超 (可能带有明确的类型参数的开头)。

  • 合格的超类构造函数调用以主 表达式开头。

它们允许子类构造函数明确关于 直接超类(§8.1.3)指定新 创建的对象的直接包容实例。当超类 是内部类时,这可能是必需的。

壳体中提出的答案最近的是

public SubClass(Outer outer) { 
    outer.super(); 
} 

要延长Outer.Inner即一个内部类的Outer,​​构造需要具有Outer一个实例,它是封闭类型。

outer.super();将调用Outer父类的构造函数,即Inner构造函数。

outer.super();语法可以是令人不安的,因为我们没有关于构造的一个参数,但在延伸的内部类的类的情况下,通常调用super(),子类的构造函数允许此语法。

+0

'outer.super()'不会编译... –

+0

@Usagi Miyamoto我刚刚尝试过。有用。 – davidxxx

+0

你的类'Outer'是否有一个名为'super()'的方法?除非这样做,'super'是一个保留字(一种语言结构),保留给超类的构造函数的调用,因此不能用类或实例标识符进行限定... –

0

我不认为,“外部”类可以扩展内部类。这个构造意味着,一个类可以访问另一个类的私有成员。

不过,您可以有一个内部类来扩展相同外部类的另一个内部类。

至于构造,外实例在实例中指定,而不是作为一个参数:

class Outer { 
    class Inner { 
     ... 
    } 
    class SubInner { 
     ... 
    } 
    void method() { 
     Inner i = this.new SubInner(); 
    } 
}