2013-08-26 40 views
5

tôi muốn làm sau điều:Làm thế nào để implictly gọi constructor của lớp cha

class P { 
    P(int a) { 
    // construct 
    } 
} 

class C extends P { 
} 

// in main 
int a = 2; 
C foo = new C(a); // can I do this? 

Tôi muốn tạo ra con đối tượng C bằng cách gọi constructor parent class P mà không cần viết bất kỳ constructor trong lớp C như "siêu (a)" . Điều đó có thể không?

Ý tưởng là tôi có nhiều lớp như "lớp C" cần chức năng hàm dựng giống như "lớp P". Vì vậy, tôi không muốn viết phương thức khởi tạo mỗi lần tôi tạo một lớp tương tự mới.

Cảm ơn

+1

Bạn không thể gọi một constructor với một cuộc tranh cãi mà không cần viết một constructor mà mất cuộc tranh cãi. Câu hỏi của bạn không có ý nghĩa. – EJP

Trả lời

3

Constructors không được kế thừa. Bạn sẽ cần phải khai báo một hàm tạo trong C để lấy một đối số. Nó sẽ cần phải gọi hàm tạo siêu lớp thích hợp (nếu bạn không muốn hàm tạo của lớp bậc trên mặc định).

Phương thức khởi tạo duy nhất bạn có thể tránh khai báo là hàm tạo mặc định, no-arg và chỉ khi bạn khai báo không có hàm tạo nào. Đó là bởi vì trình biên dịch sẽ tạo một trình cho bạn nếu bạn không có các hàm tạo nào được khai báo. Trình biên dịch luôn chèn một cuộc gọi đến hàm tạo siêu lớp mặc định trừ khi bạn gọi một hàm tạo siêu lớp một cách rõ ràng.

Cũng lưu ý rằng nếu bạn không gọi rõ ràng một hàm tạo siêu lớp và không có hàm tạo mặc định nào trong lớp cha, bạn sẽ nhận được lỗi biên dịch.

EDIT: Nếu bạn có "nhiều lớp học như lớp C", thì cách khác để viết nhiều nhà thầu là sử dụng factory method pattern. Bạn có thể có tất cả các lớp thực hiện một hàm tạo mặc định và cung cấp một phương thức riêng biệt init() lấy một bộ đối số tiêu chuẩn. Phương thức factory sẽ chấp nhận một đối tượng Class<? extends C> và một số đối số khởi tạo, tạo một cá thể mới (sử dụng hàm tạo mặc định) và gọi phương thức init của nó với các đối số khởi tạo. Bằng cách đó, bạn chỉ cần ghi đè phương thức init cho các lớp con đó cần xử lý đặc biệt (luôn nhớ gọi qua super.init).

+0

giống như: lớp công khai B {protected int a;} lớp C mở rộng B {proctected void init (int a) {this.a = a;}} lớp Nhà máy {public static C getC (Lớp c, int a) { C cInstance = c.newInstance(); cInstance.init (a); return cInstance;} lớp D mở rộng C {@override procted void init (int a) {super.init (a); ...}}? –

+0

@ user2245634 - Tôi đặt 'init' trong' B'. Ngoài ra, phương thức factory sẽ là một phương thức chung trong 'B'; bạn không cần một lớp riêng biệt.'C' và' D' sẽ không cần ghi đè 'init' vì mục đích khởi tạo' a' (mặc dù chúng có thể muốn khởi tạo khác). –

+0

cảm ơn, nhưng nếu mô hình phương thức nhà máy phải sử dụng lớp nhà máy để tạo ra cá thể, hoặc gọi B mới() và như vậy sẽ bỏ qua phương thức init –

2
  • Một constructor ngầm kêu gọi các nhà xây dựng tham số-ít của nó là siêu lớp trực tiếp (chỉ khi không có cuộc gọi rõ ràng)
  • Khi bạn định nghĩa constructor của riêng mình, các nhà xây dựng mặc định sẽ không được tạo ra.

Vì vậy, trong trường hợp của bạn Lớp C có một constructor mặc định mà sẽ cố gắng ngầm gọi constructor mặc định của lớp P mà không thoát và sẽ thất bại.

Vì vậy, bạn phải làm điều đó theo cách này

class P 
{ 
    public P(int a) 
    { 
    // construct 
    } 
} 

class C extends P 
{ 
    public C(int x) 
    { 
     super(x); 
    } 
} 
+1

Một hàm tạo mặc định ngầm gọi các hàm tạo ít tham số của lớp siêu ngay lập tức của nó ** chỉ ** nếu hàm tạo mặc định không gọi rõ ràng một hàm tạo siêu lớp. Tuy nhiên, đó là sự thật của _any_ constructor, mặc định hay không. –

+0

@TedHopp ohh yes..indeed..its áp dụng cho bất kỳ nhà xây dựng nào..đã đăng ký ans..thx – Anirudha

+0

Vâng .. chúng ta cũng phải lưu ý rằng _super (x) _ phải là dòng đầu tiên trong hàm tạo lớp con. –

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