问题描述
为什么this和super不能同时出现在一个构造函数里面?class A{ A() { System.out.println("A"); } }class B extends A{ B() { // super(); //error this(3); System.out.println("B"); } B(int x) { System.out.println("B2"); } public static void main(String[] args) { B a=new B(); }}关于this,super不是很理解。。就像上面那个例子。问1:不是每个构造函数默认第一条语句都是调用super么?反正默认也是加上,可是我加了super()以后反而会出错。。。不加没事。问2:是不是所有构造函数里面第一条语句都会调用super?还是只要一个构造函数调用一个super()其它的就不在调用了?如果按照上面的运行。我想是否应该是 先运行B()中默认的super(),这样,要先执行一次A()中的System语句,然后在回到B()中,继续运行this(3),在进入B(int x)进入后在B(int x)中在默认运行super(),在回到B()中。。。那么输出应该是 A A B2 B可是结果输出却是 A B2 B这好像说明super()只运行了一次。。那么是说this(3)中的super()没有运行么?是不是不管子类有多少个构造方法,但调用super只调用一次?谢谢,麻烦不忙时候讲讲
解决方案
简单解释:其实构造函数也是一个链条一样的东西,会调用最上面的那层钩子,然后依次不重复的往下。每个构造函数虽然原理是先调用super,但是当构造函数形成一个链条的时候,不会每次去调用,就和js的原型差不多。 之所以你的super放在哪里不对的原因是,编译器认为,你既然调用了this(3)这个构造器,那么这个构造器肯定会找到你的super并且调用,那么你在这里调用super是想迫使它调用两次父类的构造器,根据我上面的那个原理,是不成立的,所以编译不通过。 欢迎采纳,不懂的可以联系我。
解决方案二:
我已经给你回信了 你仔细看一下咯。
解决方案三:
B a=new B(); 当这样new一个a的时候 B() { -- super(); //默认的调用父类的构造函数 this(3); //这个地方不会再去掉父类的构造函数啊可以通俗的理解,这个只是调用本类的一个方法,与父类无关,不知道可不可以这样通俗理解 System.out.println("B"); }
解决方案四:
1.this和super的调用都必须是放第一句,所以不能同时调用,会冲突、、、只能选一个
解决方案五:
因为this()里面还会调用(显式或者隐式调用)一次super(),如果允许,就会导致不容易发现的问题,如赋值被覆盖等等
解决方案六:
构造函数中第一条语句可以调用父类的构造函数或本身的其它构造函数,但只能调用一个;如果构造函数中没有显性的调用其它构造函数,编译器会在构造函数中默认加上super()。你的例子中,B()中第一条语句调用了自身的B(3),B(3)中编译器默认加上了super(),于是结果就是A B2 B