一个典型的问题,关于继承成员内部类的子类的构造函数

问题描述

一个典型的问题,关于继承成员内部类的子类的构造函数

初学JAVA,没有C币,但是希望大家能够帮忙解决一下问题:
先上代码:

 package Test;
public class test9 {
    public static void main(String[] args){
        Outer outer=new Outer("test");
        new Extender(outer,10);
    }
}

class Outer{
    public Outer(String str){}
    class Inner{
        public Inner(){}
        public Inner(int a){
            System.out.println("Inner class has been created");
        }
    }
}

class Extender extends Outer.Inner{
    public Extender(Outer outer,int a){
        //outer.super(a);     //语句1
        outer.new Inner(a);  //语句2
    }
}

问题出在对Extender类的构造函数的定义上:
之前都一直习惯,直接在构造函数的首行显示引用超构造函数,但是也是一知半解。前几天突然发现这个问题:
我们都知道,super这个关键字其实就是代替了一段字符串“new 父类名”,所以我就想既然用“outer.super(a)”能够编译通过,那“outer.new Inner(a)”应该也能编译通过,于是我做了以下几个实验:
1、执行语句1,不执行语句2:编译通过,打印出“Inner class has been created"
2、执行语句1,也执行语句2:编译通过,打印出两行“Inner class has been created”
3、不执行语句1,执行语句2:编译不通过,报错:“由于某些中间构造函数调用,没有任何类型 Outer 的外层实例可用”

我想不明白的就是,既然实验2中,new outer.Inner(a)能够创建对象成功,为什么在实验3里面,单独运行时就报错呢???

解决方案

java内部类的构造器必须连接到指向其外围类对象的引用,也就是构造内部类必须给它一个外部类对象的引用,内部类依赖于外部类对象,因此在继承内部类的时候,需要在继承类中的构造器中手动加入对基类(外围类)构造器的调用。因为,在继承类实例化时,并不存在一个外围类对象,以让继承类的实例去连接到外围类。所以,我们需要创建一个外围类,然后用一个特定的语法来表明内部类与外围类的关系.
题主上文中的第三个实验并没有调用外围类的构造器,而只是建立了一个内部类实例而已,这个和外围类的构造是没有关系的

解决方案二:

首先我也是刚刚接触java,看你这个题也挺有意思,也来凑凑热闹
No enclosing instance of type Outer is available due to some intermediate constructor invocation
提示的错误我用有道翻译了下大概意思是这样的:由于某些构造函数的调用,没有Outer内部的实例;
我的理解是outer.new Inner(a);这句只是创建了一个实例,并非调用父类的构造函数,我做了一下试验:
1 。outer.super(a); //语句1
2 。 Outer.Inner in=outer.new Inner(a);//语句2
将语句1.2全注释了,结果提示错误跟上面一样。然后又将语句2加上父类的引用是可以的,也就印证了我的想法,语句2只是创建了一个实例,而非初始父类,要初始化父类构造函数必须用super;课上老师也说到过隐式的调用是在你没有写构造函数时默认给一个super(),这里我也试过将Inner里的构造都注释调不过依然会报同样的错误,所以我又把Outer里的构造也一起都注释掉了,改成继承为Outer结果语句2就可以单独存在了。综上所述:我的理解是隐式的构造传递只会给你传一个super(),而不会是out.super();而你的语句2充其量只是一个实例。这个问题应该是编译器的问题吧?所以我也找不到答案,希望大神能过解惑!

时间: 2024-10-30 10:27:32

一个典型的问题,关于继承成员内部类的子类的构造函数的相关文章

问一个Java泛型与类继承的问题

问题描述 问一个Java泛型与类继承的问题 直接上代码了 //DeviceRepository类 public abstract class DeviceRepository<T extends Device> extends DomainRepository<T> //DeviceEventHandler类第一种写法 public abstract class DeviceEventHandler<M extends Device,R extends DeviceRepos

javascript-Javascript,一个通用的实现类继承的函数

问题描述 Javascript,一个通用的实现类继承的函数 var A = function() { this.a = 3; } var B = function() { this.b = 6; } function ext(A, B) { var subclass = B; //構造一個新的同名類類,用他來繼承父類,並且調用子類都構造函數 var B = function() { A.apply(this.arguments); subclass.apply(this.arguments);

一个典型kernel bug的追踪之(一)

原文链接 :  http://kerneldedup.org/forum/forum.php?mod=viewthread&tid=17&extra=page%3D1 一个典型kernel bug的追踪之(一):出错现场分析 昨天偶尔在跑测试的时候发现uksmd的一个极其罕见出现的bug(在一个很难进入的路径上,很久很久没有碰到类似的问题了),本质上属于一个soft lockup的bug.所谓,soft lockup就是说,这个bug没有让系统彻底死机,但是若干个进程(或者kernel t

不少应用在中国都遇到了水土不服的情况,Google地图又是其中的一个典型

很多Android用户都是Google的粉丝,对Google情有独钟,Android设备上所安装的都是Google的原生应用,如Google Play市场,Google Search等等.但是,由于种种原因,不少应用在中国都遇到了水土不服的情况,Google地图又是其中的一个典型. Google地图在中国水土不服软件名称:谷歌地图(Google Maps)软件版本:6.9.1 官方版软件大小:8.27MB软件授权:免费适用平台:Android下载地址:http://dl.pconline.com

第6周-任务1-使用常对象的一个典型错误

[题目]下面的程序存在编译错误.有两种方法可以修改,请给出这两种修改方案,在报告中说明你倾向于用哪一种?为什么?处理此类问题的原则是什么? class C {private: int x; public: C(int x){this->x= x;} int getX(){return x;} }; void main() { const C c(5); cout<<c.getX(); //这一行将会出现错误 system("pause"); } [分析]这个程序中的问

java+ 程序 子类继承父类 创建子类对象时构造方法中无显示调用父类构造方法

问题描述 java+ 程序 子类继承父类 创建子类对象时构造方法中无显示调用父类构造方法 创建子类对象时,Student s = new Student(""school""); 该构造方法中没有显示调用父类的构造方法,但还是编译成功了,该构造方法调用自身的构造函数,此构造函数中有调用父类的构造方法,执行成功的原因是什么 解决方案 不用显示调用,会自动执行父类的构造 解决方案二: 子类的构造方法中,如果没有显示调用父类的构造方法,会默认调用父类无参的构造方法.类似于

一个典型PHP支付系统的设计与实现

  由于公司业务需要,花两周时间实现了一个小型的支付系统,麻雀虽小五脏俱全,各种必须的模块如账户加锁,事务性保证,流水对帐等都是有完整实现的,整个开发过程中有很多经验积累,再加上在网上搜索了一下,大部分都是些研究性的论文,对实际使用价值不大,所以这次特意拿出来和大家分享一下. 这个系统可以用作小型支付系统,也可以用做第三方应用接入开放平台时的支付流水系统. 原来的需求比较负责,我简化一点说: 对每个应用,对外需要提供 获取余额,支付设备,充值 等接口 后台有程序,每月一号进行清算 账户可以被冻结

安装使用MySQL时一个典型错误的解决

mysql|错误|解决     偶在Linux上顺利安装mysql,apache,php之后,编了一个连接数据库的.php页面,报如下错误:    Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock'    偶在网上搜了下,还是个很典型的错误,偶在google上搜了一些资料,成功解决.偶采取如下方法:        看看mysql的错误日志就明白怎么回事,我这里的错误日志是在/var/lib/

一个农民,一个典型高新技术企业办公场所

在杭州市文三路昌地火炬的14层有500多平方现代化办公面积,这就是丁国栋所创立的新型电子商务平台"际通宝(www.gtobal.net)"的总部.精装修的办公场地,清一色联想品牌电脑,70多个摆放整齐的V字形写字台,是典型的高新技术企业办公场所,怎么也无法与一个农民联系起来. 记者见到丁国栋时,他正在跟几个技术人员讨论"野娇娇网上商城"的团购功能实现问题,这是丁国栋创立际通宝以来与传统行业企业家合作运营的第16个电子商务平台,这个平台5年的开发.运营.推广.改进以及