2012-04-30 72 views

Trả lời

25

this(...) sẽ gọi một hàm tạo khác trong cùng một lớp trong khi super() sẽ gọi một hàm tạo siêu. Nếu không có super() trong một hàm tạo, trình biên dịch sẽ thêm một ngầm.

Vì vậy, nếu cả hai được cho phép, bạn có thể kết thúc việc gọi hàm dựng super hai lần.

Ví dụ (không tìm kiếm một cảm giác trong các tham số):

class A { 
    public A() { 
    this(false); 
    } 

    public A(boolean someFlag) { 
    } 
} 

class B extends A { 
    public B() { 
    super(); 
    } 

    public B(boolean someFlag) { 
    super(someFlag); 
    } 

    public B (int someNumber) { 
    this(); // 
    } 
} 

Bây giờ, nếu bạn gọi new B(5) các nhà thầu sau đây được gọi:

 this(false); 
A() ---------------> A(false) 
^ 
| 
| super(); 
| 
|  this(); 
B() <--------------- B(5) <--- you start here 

Cập nhật:

Nếu bạn có thể sử dụng this()super(), bạn có thể kết thúc với som ething như thế này:

(Attention: đây có nghĩa là để hiển thị những gì có thể đi sai, nếu bạn được phép làm điều đó - mà bạn may mắn là không)

 this(false); 
A() ---------------> A(false) 
^     ^
|     | 
| super();   | super(true); <--- Problem: should the parameter be true or false? 
|     | 
|  this();  | 
B() <--------------- B(5) <--- you start here 

Như bạn có thể thấy, bạn sẽ gặp phải vấn đề trong đó hàm tạo A(boolean) có thể được gọi với các tham số khác nhau và bây giờ bạn phải quyết định cách nào nên được sử dụng. Ngoài ra, các nhà thầu khác (A()B()) có thể chứa mã mà hiện tại có thể không được gọi chính xác (ví dụ: không đúng thứ tự, vv) vì cuộc gọi đến super(true) sẽ phá vỡ chúng trong khi this() thì không.

4

Cả hai this()super() là các cuộc gọi hàm tạo và cuộc gọi hàm tạo phải là cuộc gọi đầu tiên (và chỉ đầu tiên) trong một hàm tạo. Nếu không, hàm tạo Object sẽ được gọi nhiều lần khi khởi tạo một đối tượng đơn lẻ.

6

Có sự khác biệt giữa super()this().

super() - gọi hàm tạo lớp cơ sở trong khi
this() - gọi hàm tạo lớp hiện tại.

Cả hai this()super() là các cuộc gọi hàm tạo.
Lệnh gọi hàm xây dựng phải luôn là câu lệnh đầu tiên. Vì vậy, chúng ta không thể có hai câu lệnh như câu lệnh đầu tiên, do đó chúng ta có thể gọi super() hoặc chúng ta có thể gọi this() từ hàm tạo, nhưng không phải cả hai.

+0

cơ bản tại một thời gian chỉ có một câu lệnh được sử dụng, điều gì làm u có nghĩa là "chúng ta không thể có hai câu lệnh như câu lệnh đầu tiên", nó không có ý nghĩa gì –

+0

đó là điều tôi đã nói .. –

0

Bởi vì nó không có ý nghĩa. Nhà xây dựng phải gọi this() hoặc super() (ẩn hoặc rõ ràng).this() gọi một hàm tạo khác phải gọi this() hoặc super() v.v. Một nhà xây dựng được gọi là cả hai số this()super() do đó cuối cùng sẽ gọi số super() hai lần.

2
  • chúng tôi sử dụng này() từ khóa trong constructor chaining để truy cập constructor của lớp cùng
  • chúng tôi sử dụng siêu() từ khóa khi chúng ta muốn truy cập vào constructor của lớp cha mẹ ngay lập tức di sản.

Và có điều kiện ở cả hai điều kiện phải được khai báo trong dòng dòng đầu tiên của hàm tạo bạn đang sử dụng. Và đó là lý do tại sao chúng tôi không thể sử dụng cả hai trong một nhà xây dựng duy nhất bởi vì bạn chỉ có thể viết một điều trong số dòng đầu tiên của mình.

0

So sánh ví dụ bên dưới. Class FirstChild đặt tên biến thể hiện trong 2 constructor khi gọi hàm khởi tạo thứ hai từ hàm khởi đầu thứ nhất bị loại trừ bởi cần gọi super().

Trong lớp SecondChild có giới thiệu hàm tạo riêng thứ ba nhận 2 tham số - đầu tiên được truyền cho supper() và thứ hai được dùng để đặt tên. 2 nhà xây dựng đầu tiên đang gọi cho nhà thầu thứ ba. Super() được gọi chính xác một lần, biến thể hiện cũng chỉ được đặt trong một hàm tạo. Mã tạo ra cùng một kết quả mà không cần gọi super() và this() trong cùng một hàm tạo.

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()); 
    } 
} 
0

Bởi vì nếu bạn sử dụng this()super() với nhau trong một nhà xây dựng nó sẽ cho biên dịch lỗi thời gian. Vì this()super() phải là tuyên bố thực thi đầu tiên. Nếu bạn viết this() trước super() sẽ trở thành câu lệnh thứ hai và ngược lại. Đó là lý do tại sao chúng tôi không thể sử dụng this()super() cùng nhau.

0

this() và super(), cả hai đều là các hàm tạo nên đó là lý do tại sao phải là câu lệnh đầu tiên. Nhưng chúng ta có thể sử dụng cả hai trong một chương trình.

this(): Được sử dụng để gọi, cùng một lớp Constructor mặc định hoặc được tham số.

super(): Nó được sử dụng để gọi, ngay lập tức siêu/cha mẹ lớp Mặc định hoặc Parametrized Constructor.

//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); 
    } 
} 
Các vấn đề liên quan