2010-02-23 40 views

Trả lời

43

Các trình xây dựng không được kế thừa, bạn phải tạo một hàm tạo mới, giống hệt nguyên mẫu trong lớp con ánh xạ tới hàm tạo tương ứng của nó trong lớp cha.

Dưới đây là một ví dụ về cách làm việc này:

class Foo { 
    Foo(String str) { } 
} 

class Bar extends Foo { 
    Bar(String str) { 
     // Here I am explicitly calling the superclass 
     // constructor - since constructors are not inherited 
     // you must chain them like this. 
     super(str); 
    } 
} 
+1

Ngay cả khi một lập trình viên Java không phải là n00b, điều đó không rõ ràng với tôi. Bạn có thể làm rõ? –

+0

@Bears sẽ ăn bạn: Nếu lớp cha có một hàm tạo như sau: 'public class (String arg1) {/ * implementation here/*}' thì lớp con cần một kiểu như sau: 'public Subclass (String arg1) { siêu (arg1); } ' – Powerlord

+0

Điều đó nghe giống như một cách ưa thích để nói" sử dụng 'super' trong hàm tạo của lớp con". Tôi không có ý tưởng những gì một nguyên mẫu constructor là trong Java. –

3

Tìm hiểu về bộ super keyword (Cuộn xuống Constructors Subclass). Nếu tôi hiểu câu hỏi của bạn, bạn có thể muốn gọi một hàm tạo siêu lớp? Cần chú ý rằng trình biên dịch Java sẽ tự động đặt trong một cuộc gọi hàm tạo no-arg tới siêu lớp nếu bạn không gọi một constructor superclass một cách rõ ràng.

1

Giả sử nếu bạn có

/** 
* 
*/ 
public KKSSocket(final KKSApp app, final String name) { 
    this.app = app; 
    this.name = name; 
    ... 
} 

sau đó một sub-class tên KKSUDPSocket mở rộng KKSSocket có thể có:

/** 
* @param app 
* @param path 
* @param remoteAddr 
*/ 
public KKSUDPSocket(KKSApp app, String path, KKSAddress remoteAddr) { 
    super(app, path, remoteAddr); 
} 

/** 
* @param app 
* @param path 
*/ 
public KKSUDPSocket(KKSApp app, String path) { 
    super(app, path); 
} 

Bạn chỉ cần vượt qua các đối số lên các nhà xây dựng chuỗi, giống như các cuộc gọi phương thức đến các lớp siêu, nhưng sử dụng siêu (...) tham chiếu đến siêu lớp c onstructor và pass trong args đã cho.

5

Nhà xây dựng mặc định - nhà thầu công khai với các đối số ngoài (được khai báo hoặc ngụ ý) - được kế thừa theo mặc định. Bạn có thể thử các mã sau đây cho một ví dụ về điều này:

public class CtorTest { 
    public static void main(String[] args) { 
     final Sub sub = new Sub(); 
     System.err.println("Finished."); 
    } 

    private static class Base { 
     public Base() { 
      System.err.println("In Base ctor"); 
     } 
    } 

    private static class Sub extends Base { 
     public Sub() { 
      System.err.println("In Sub ctor"); 
     } 
    } 
} 

Nếu bạn muốn gọi một cách rõ ràng một nhà xây dựng từ một lớp siêu, bạn cần phải làm điều gì đó như thế này:

public class Ctor2Test { 
    public static void main(String[] args) { 
     final Sub sub = new Sub(); 
     System.err.println("Finished."); 
    } 

    private static class Base { 
     public Base() { 
      System.err.println("In Base ctor"); 
     } 

     public Base(final String toPrint) { 
      System.err.println("In Base ctor. To Print: " + toPrint); 
     } 
    } 

    private static class Sub extends Base { 
     public Sub() { 
      super("Hello World!"); 
      System.err.println("In Sub ctor"); 
     } 
    } 
} 

Thông báo trước là lệnh gọi super() phải đến như là dòng đầu tiên của hàm tạo của bạn, nếu không trình biên dịch sẽ phát điên với bạn.

+1

Các hàm tạo mặc định không thực sự là "kế thừa". Nếu một constructor không có đối số (AKA default) tồn tại trong superclass và không được định nghĩa rõ ràng trong lớp con, và nếu lớp con cũng không có bất kỳ constructor được định nghĩa rõ ràng nào (có nghĩa là, constructors with parameters), thì trình biên dịch sẽ tự động chèn vào lớp con một hàm tạo không đối số công khai chỉ chứa 'super();'. Điều này gọi hàm tạo mặc định của lớp cha. – hotshot309

11

Hàm tạo siêu lớp KHÔNG thể được kế thừa trong lớp mở rộng. Mặc dù nó có thể được gọi trong constructor của lớp mở rộng với super() như là câu lệnh đầu tiên.

+0

Có ... hoặc bạn có thể gọi bất kỳ biến thể nào của hàm tạo của lớp cha mà bạn muốn sử dụng (nó có thể không có đối số, như @GoodManish đã nói, hoặc nó có thể có nhiều hơn). Cũng có các tình huống trong đó 'super();' sẽ được trình biên dịch gọi một cách rõ ràng trước khi phần còn lại của phần thân của bất kỳ các hàm tạo nào của bạn được thực thi. – hotshot309

1

Bạn thừa hưởng thuộc tính lớp, không constructor của lớp cha .Đây là cách nó đi:

Nếu không có nhà xây dựng được thêm vào trong các lớp siêu, nếu không thì trình biên dịch cho biết thêm một contructor không tranh cãi. Hàm khởi tạo mặc định này được gọi ngầm bất cứ khi nào một cá thể mới của lớp con được tạo ra. Ở đây, lớp con có thể hoặc không có hàm tạo, tất cả đều ổn.

nếu một hàm tạo được cung cấp trong lớp siêu, trình biên dịch sẽ xem liệu nó có phải là một hàm tạo arg không hoặc một hàm tạo với các tham số.

nếu không có args, trình biên dịch sẽ gọi nó cho bất kỳ lớp phụ nào. Ở đây cũng là lớp phụ có thể hoặc có thể không có hàm tạo, tất cả đều ổn.

nếu 1 hoặc nhiều contructor trong lớp cha có tham số và không có hàm tạo args vắng mặt, thì lớp con phải có ít nhất 1 hàm tạo trong đó hàm gọi ngầm cho cấu trúc lớp cha được tạo thông qua siêu (parent_contractor params).

theo cách này bạn chắc chắn rằng các thuộc tính lớp kế thừa luôn được instanciated.

+0

"trình biên dịch sẽ gọi nó cho bất kỳ lớp phụ instanciation" - có vẻ như là điểm ở trên là bạn phải rõ ràng gọi super() nếu lớp con của bạn có một constructor no-arg. – Vlad

Các vấn đề liên quan