Java 为什么可以';this()和super()不能在构造函数中同时使用吗?
为什么在构造函数中不能同时使用Java 为什么可以';this()和super()不能在构造函数中同时使用吗?,java,inheritance,constructor,Java,Inheritance,Constructor,为什么在构造函数中不能同时使用this()和super() 合并这样一个东西的原因是什么?this()和super()都是构造函数调用,构造函数调用必须是构造函数中的第一个(也是唯一的第一个)调用。否则,当实例化单个对象时,对象构造函数将被多次调用。此(…)将调用同一类中的另一个构造函数,而super()将调用超级构造函数。如果构造函数中没有super(),编译器将隐式添加一个 因此,如果这两种方法都被允许,您可能会调用super构造函数两次 示例(不要在参数中寻找意义): 现在,如果调用new
this()
和super()
合并这样一个东西的原因是什么?this()和super()
都是构造函数调用,构造函数调用必须是构造函数中的第一个(也是唯一的第一个)调用。否则,当实例化单个对象时,对象
构造函数将被多次调用。此(…)
将调用同一类中的另一个构造函数,而super()
将调用超级构造函数。如果构造函数中没有super()
,编译器将隐式添加一个
因此,如果这两种方法都被允许,您可能会调用super
构造函数两次
示例(不要在参数中寻找意义):
现在,如果调用newb(5)
将调用以下构造函数:
this( false);
A() ---------------> A(false)
^
|
| super();
|
| this();
B() <--------------- B(5) <--- you start here
正如您所看到的,您会遇到这样一个问题:可以使用不同的参数调用
a(boolean)
构造函数,现在您必须以某种方式决定应该使用哪个构造函数。此外,其他构造函数(A()
和B()
)可能包含现在可能无法正确调用的代码(即,无序等),因为对super(true)
的调用将绕过它们,而this()
则不会。super()
和this()
之间存在差异
super()
-调用基类构造函数,而this()
-调用当前类构造函数
class FirstChild extends ConstructorTest{
private String name = null;
public FirstChild(){
super("super text 1");
//this("Unknown"); //UNCOMMENTED DOES NOT COMPILE
name = "Unknown";
}
public FirstChild(String name){
super("super text 2");
this.name = name;
}
public String getName(){
return name;
}
}
class SecondChild extends ConstructorTest{
private String name = null;
public SecondChild(){
this("super text 1", "Unknown");
}
public SecondChild(String name){
this("super text 2", name);
}
private SecondChild(String superStr, String name)
{
super(superStr);
this.name = name;
}
public String getName(){
return name;
}
}
public class ConstructorTest{
public ConstructorTest(String str){
System.out.println("ConstructorTest constructor called with parameter \"" + str + "\"");
}
public static void main(String... args)
{
System.out.println("Hello from main, FirstChild results:");
FirstChild fc1 = new FirstChild();
FirstChild fc2 = new FirstChild("John");
System.out.println(" child fc1 name: " + fc1.getName());
System.out.println(" child fc2 name: " + fc2.getName());
System.out.println("Hello from main, SecondChild results:");
SecondChild sc1 = new SecondChild();
SecondChild sc2 = new SecondChild("John");
System.out.println(" child sc1 name: " + sc1.getName());
System.out.println(" child sc2 name: " + sc2.getName());
}
}
//Super Class
public class SuperConstructor {
SuperConstructor(){
this(10);
System.out.println("Super DC");
}
SuperConstructor(int a){
this(10,20);
System.out.println("Suer SPC with Iteger");
}
SuperConstructor(int i,int j){
System.out.println("Super with DPC with Iteger and Integer");
}
}
//subclass
public class ThisConstructor extends SuperConstructor{
ThisConstructor(){
this(10,20);
System.out.println("Subcalss DC ");//DC Default Constructor
}
ThisConstructor(int i){
super(i);
System.out.println("Subcalss SPC with Iteger");//SPC Single Parameterized Constructor
}
ThisConstructor(int i, String s){
this();
System.out.println("Subcalss DPC with Iteger and String");//DPC double Parameterized Constructor
}
ThisConstructor(int i,int age){
super(i,age);
System.out.println("Subcalss DPC with Iteger and Integer");
}
public static void main(String []k){
System.out.println("=================Frist time Calling ==========================\n");
ThisConstructor t = new ThisConstructor(1);
System.out.println("=================Second time Calling ==========================\n");
ThisConstructor t1 = new ThisConstructor(1,2);
}
}
this()
和super()
都是构造函数调用。构造函数调用必须始终是第一条语句。因此,您可以使用
super()
或this()
作为第一个语句。,因为它没有意义。构造函数必须调用this()
或super()
(隐式或显式)this()
调用另一个构造函数,该构造函数必须像以前一样调用this()
或super()
等。因此,同时调用this()
和super()
的构造函数最终将调用super()
两次。- 我们在构造函数链接中使用this()关键字来访问同一类的构造函数
- 当我们想在继承中访问直接父类的构造函数时,我们使用super()关键字
两者都有一个条件,它们必须在您使用的构造函数的第一行声明。这就是为什么我们不能在一个构造函数中同时使用这两个函数的原因,因为您只能在第一行中编写一个函数。比较下面的示例。类FirstChild在两个构造函数中设置实例变量名,因为调用第一个构造函数中的第二个构造函数不需要调用super() 在SecondChild类中引入了第三个私有构造函数,它接受两个参数——第一个参数传递给super(),第二个参数用于设置名称。前两个构造函数正在调用第三个构造函数。Super()只调用一次,实例变量也只在一个构造函数中设置。代码生成相同的结果,而不需要在同一构造函数中调用super()和this()
class FirstChild extends ConstructorTest{
private String name = null;
public FirstChild(){
super("super text 1");
//this("Unknown"); //UNCOMMENTED DOES NOT COMPILE
name = "Unknown";
}
public FirstChild(String name){
super("super text 2");
this.name = name;
}
public String getName(){
return name;
}
}
class SecondChild extends ConstructorTest{
private String name = null;
public SecondChild(){
this("super text 1", "Unknown");
}
public SecondChild(String name){
this("super text 2", name);
}
private SecondChild(String superStr, String name)
{
super(superStr);
this.name = name;
}
public String getName(){
return name;
}
}
public class ConstructorTest{
public ConstructorTest(String str){
System.out.println("ConstructorTest constructor called with parameter \"" + str + "\"");
}
public static void main(String... args)
{
System.out.println("Hello from main, FirstChild results:");
FirstChild fc1 = new FirstChild();
FirstChild fc2 = new FirstChild("John");
System.out.println(" child fc1 name: " + fc1.getName());
System.out.println(" child fc2 name: " + fc2.getName());
System.out.println("Hello from main, SecondChild results:");
SecondChild sc1 = new SecondChild();
SecondChild sc2 = new SecondChild("John");
System.out.println(" child sc1 name: " + sc1.getName());
System.out.println(" child sc2 name: " + sc2.getName());
}
}
//Super Class
public class SuperConstructor {
SuperConstructor(){
this(10);
System.out.println("Super DC");
}
SuperConstructor(int a){
this(10,20);
System.out.println("Suer SPC with Iteger");
}
SuperConstructor(int i,int j){
System.out.println("Super with DPC with Iteger and Integer");
}
}
//subclass
public class ThisConstructor extends SuperConstructor{
ThisConstructor(){
this(10,20);
System.out.println("Subcalss DC ");//DC Default Constructor
}
ThisConstructor(int i){
super(i);
System.out.println("Subcalss SPC with Iteger");//SPC Single Parameterized Constructor
}
ThisConstructor(int i, String s){
this();
System.out.println("Subcalss DPC with Iteger and String");//DPC double Parameterized Constructor
}
ThisConstructor(int i,int age){
super(i,age);
System.out.println("Subcalss DPC with Iteger and Integer");
}
public static void main(String []k){
System.out.println("=================Frist time Calling ==========================\n");
ThisConstructor t = new ThisConstructor(1);
System.out.println("=================Second time Calling ==========================\n");
ThisConstructor t1 = new ThisConstructor(1,2);
}
}
因为如果在构造函数中同时使用
this()
和super()。因为this()
和super()
必须是第一条可执行语句。如果先编写this()
,则super()
将成为第二条语句,反之亦然。这就是为什么我们不能同时使用this()
和super() this()和super()都是构造函数,所以必须是第一条语句。但我们可以在程序中同时使用这两种方法
this():用于调用同一类的默认构造函数或参数化构造函数
class FirstChild extends ConstructorTest{
private String name = null;
public FirstChild(){
super("super text 1");
//this("Unknown"); //UNCOMMENTED DOES NOT COMPILE
name = "Unknown";
}
public FirstChild(String name){
super("super text 2");
this.name = name;
}
public String getName(){
return name;
}
}
class SecondChild extends ConstructorTest{
private String name = null;
public SecondChild(){
this("super text 1", "Unknown");
}
public SecondChild(String name){
this("super text 2", name);
}
private SecondChild(String superStr, String name)
{
super(superStr);
this.name = name;
}
public String getName(){
return name;
}
}
public class ConstructorTest{
public ConstructorTest(String str){
System.out.println("ConstructorTest constructor called with parameter \"" + str + "\"");
}
public static void main(String... args)
{
System.out.println("Hello from main, FirstChild results:");
FirstChild fc1 = new FirstChild();
FirstChild fc2 = new FirstChild("John");
System.out.println(" child fc1 name: " + fc1.getName());
System.out.println(" child fc2 name: " + fc2.getName());
System.out.println("Hello from main, SecondChild results:");
SecondChild sc1 = new SecondChild();
SecondChild sc2 = new SecondChild("John");
System.out.println(" child sc1 name: " + sc1.getName());
System.out.println(" child sc2 name: " + sc2.getName());
}
}
//Super Class
public class SuperConstructor {
SuperConstructor(){
this(10);
System.out.println("Super DC");
}
SuperConstructor(int a){
this(10,20);
System.out.println("Suer SPC with Iteger");
}
SuperConstructor(int i,int j){
System.out.println("Super with DPC with Iteger and Integer");
}
}
//subclass
public class ThisConstructor extends SuperConstructor{
ThisConstructor(){
this(10,20);
System.out.println("Subcalss DC ");//DC Default Constructor
}
ThisConstructor(int i){
super(i);
System.out.println("Subcalss SPC with Iteger");//SPC Single Parameterized Constructor
}
ThisConstructor(int i, String s){
this();
System.out.println("Subcalss DPC with Iteger and String");//DPC double Parameterized Constructor
}
ThisConstructor(int i,int age){
super(i,age);
System.out.println("Subcalss DPC with Iteger and Integer");
}
public static void main(String []k){
System.out.println("=================Frist time Calling ==========================\n");
ThisConstructor t = new ThisConstructor(1);
System.out.println("=================Second time Calling ==========================\n");
ThisConstructor t1 = new ThisConstructor(1,2);
}
}
super():用于调用立即超级/父类默认或参数化构造函数
class FirstChild extends ConstructorTest{
private String name = null;
public FirstChild(){
super("super text 1");
//this("Unknown"); //UNCOMMENTED DOES NOT COMPILE
name = "Unknown";
}
public FirstChild(String name){
super("super text 2");
this.name = name;
}
public String getName(){
return name;
}
}
class SecondChild extends ConstructorTest{
private String name = null;
public SecondChild(){
this("super text 1", "Unknown");
}
public SecondChild(String name){
this("super text 2", name);
}
private SecondChild(String superStr, String name)
{
super(superStr);
this.name = name;
}
public String getName(){
return name;
}
}
public class ConstructorTest{
public ConstructorTest(String str){
System.out.println("ConstructorTest constructor called with parameter \"" + str + "\"");
}
public static void main(String... args)
{
System.out.println("Hello from main, FirstChild results:");
FirstChild fc1 = new FirstChild();
FirstChild fc2 = new FirstChild("John");
System.out.println(" child fc1 name: " + fc1.getName());
System.out.println(" child fc2 name: " + fc2.getName());
System.out.println("Hello from main, SecondChild results:");
SecondChild sc1 = new SecondChild();
SecondChild sc2 = new SecondChild("John");
System.out.println(" child sc1 name: " + sc1.getName());
System.out.println(" child sc2 name: " + sc2.getName());
}
}
//Super Class
public class SuperConstructor {
SuperConstructor(){
this(10);
System.out.println("Super DC");
}
SuperConstructor(int a){
this(10,20);
System.out.println("Suer SPC with Iteger");
}
SuperConstructor(int i,int j){
System.out.println("Super with DPC with Iteger and Integer");
}
}
//subclass
public class ThisConstructor extends SuperConstructor{
ThisConstructor(){
this(10,20);
System.out.println("Subcalss DC ");//DC Default Constructor
}
ThisConstructor(int i){
super(i);
System.out.println("Subcalss SPC with Iteger");//SPC Single Parameterized Constructor
}
ThisConstructor(int i, String s){
this();
System.out.println("Subcalss DPC with Iteger and String");//DPC double Parameterized Constructor
}
ThisConstructor(int i,int age){
super(i,age);
System.out.println("Subcalss DPC with Iteger and Integer");
}
public static void main(String []k){
System.out.println("=================Frist time Calling ==========================\n");
ThisConstructor t = new ThisConstructor(1);
System.out.println("=================Second time Calling ==========================\n");
ThisConstructor t1 = new ThisConstructor(1,2);
}
}
super()-引用直接父类实例。
可用于调用直接父类方法。
this()-引用当前类实例。
可用于调用当前类方法。不能在构造函数中同时使用this()和super(),因为this()和super()必须首先在构造函数块中执行。否则它将显示编译器错误,因为构造函数调用必须是方法中的第一条语句,因此如果我们在方法中同时定义this()和super构造函数,然后它将变成冲突,如下所示。
假设先调用此构造函数,然后它将检查当前类构造函数,如果在当前类构造函数中有另一个方法调用或语句。因此,在这个调用中,当前类构造函数中的所有方法和语句都将在调用超级类构造函数之前被调用,然后它将拒绝“构造函数调用必须是方法中的第一个语句”的语句。基本上一次只使用一个语句,这是什么意思“我们不能有两个陈述作为第一个陈述”,这对于如何翻译没有任何意义: