2011-01-25 6 views
32

Không thể tạo một đối tượng bằng cách gọi trực tiếp hàm tạo của lớp abstract. Hàm khởi tạo của lớp abstract có thể được gọi chỉ từ một lớp dẫn xuất. Do đó, có vẻ là đối với tôi rằng các hàm tạo của lớp trừu tượng phải là protected hoặc gói riêng tư (sau này cho các trường hợp bất thường hạn chế sử dụng hàm tạo cho các lớp dẫn xuất trong gói). Tuy nhiên, Java cho phép hàm tạo của lớp abstractpublic.Có lý do chính đáng cho một nhà xây dựng công cộng của một lớp trừu tượng

Có bất kỳ hoàn cảnh trong đó nó là hữu ích tuyên bố các nhà xây dựng của một lớp abstractpublic, chứ không phải là protected hoặc gói-tư nhân?

Đây không hoàn toàn trùng lặp với câu hỏi "Abstract class constructor access modifier": rõ ràng bạn có thể tuyên bố một hàm tạo là public; Tôi muốn biết liệu có bao giờ có bất kỳ lý do nào để làm như vậy không. tốt. Dường như với tôi rằng không có. Tôi thấy rằng C# has a similar peculiarity.

+0

Constructor không liên quan gì đến "Tạo" đối tượng. Nó chỉ là một phương thức được gọi trong khi "tạo" một đối tượng. Do đó, lớp Tóm tắt có thể có các hàm tạo công khai sẽ được gọi trong khi tạo cá thể của lớp Tóm tắt (qua Lớp con) và trong phương thức hàm dựng đó, bạn sẽ viết mã để khởi tạo các biến thành viên. http://stackoverflow.com/questions/260666/can-an-abstract-class-have-a-constructor?lq=1 –

+1

Constructors cũng có thể là 'private', có thể được sử dụng trong chain constructor. –

Trả lời

16

Câu trả lời là như nhau cho java:

không có lý do cho một nhà xây dựng công cộng cho một lớp trừu tượng. Tôi cho rằng lý do mà trình biên dịch không phàn nàn đơn giản là họ không dành nhiều thời gian cho việc đó vì nó thực sự không quan trọng nếu nó được công khai hay được bảo vệ. (source)

Bạn không thể gọi hàm tạo của lớp trừu tượng từ bất kỳ thứ gì khác ngoài phân lớp trực tiếp.

Vì vậy việc thêm quy tắc đặc biệt cho công cụ sửa đổi truy cập của các hàm tạo của lớp trừu tượng sẽ không thêm điều gì đó hữu ích cho ngôn ngữ.


Một điều đó trông giống như một ngoại lệ từ quy tắc này - nếu lớp trừu tượng chỉ định nghĩa một constructor mặc định, sau đó các lớp con không nhất thiết phải thực hiện một constructor: đây là quy phạm pháp luật:

public abstract class A { 
    public A() {} 
} 

public class B extends A {} 

Vì vậy, chúng tôi có thể tạo B bằng cách gọi new B() - nhưng lưu ý rằng chúng tôi vẫn là tạo một B chứ không phải là A. Và, một lần nữa, nó không quan trọng nếu các nhà xây dựng trong A là công cộng hoặc được bảo vệ. Nó chỉ không nên tin, nhưng trình biên dịch sẽ thông báo và khiếu nại ...

Trên thực tế chúng ta gọi là "vô hình" constructor mặc định nào về B mà hiện một super() gọi đơn giản ...

-8

Bạn có thể có một hàm tạo công khai nếu bạn không định nghĩa trong một hàm tạo trong lớp con. dụ

abstract class Animal { 
    String name; 
    public void Animal(String name) { 
     this.name = name; 
    } 
} 


class Cat extends Animal{ 
    public String sayMayName() { 
     return this.name; 
    } 
} 

myCat = new Cat("tester"); 

name = myCat.sayMyName(); 

nếu không có constructor được định nghĩa các nhà xây dựng tầng lớp phụ huynh sẽ được gọi, nếu nó không phải là công nó sẽ không hoạt động. Điều này tôi nghĩ là thanh lịch hơn được thực hiện với một mô hình nhà máy, nhưng tôi đã sử dụng nó trong thực tế trong PHP và nó hoạt động tốt.

+3

Điều này không hoạt động trong Java. Ngoài ra, bạn không định nghĩa một hàm tạo trong lớp 'Động vật', bởi vì bạn chỉ định một kiểu trả về (' void'). –

+2

Điều này sẽ không biên dịch - một hàm tạo là * required * trong 'Cat' vì' Animal' có một hàm tạo (không mặc định) ('public void Animal (String name)' không phải là hàm tạo) –

+0

Điều này sẽ chỉ hoạt động với một constructor no-arg. Hãy thử nó, mã của bạn sẽ không biên dịch. Nhưng hàm tạo ngầm mặc định sẽ luôn có khả năng hiển thị của chính lớp đó, bất kể hàm tạo của lớp bậc trên là gì. – biziclop

-7

Gọi tôi là kẻ dị giáo, nhưng ... Tôi thấy ít nhất một lần sử dụng cho một hàm tạo trong lớp trừu tượng.

Tức là: để chỉ định tham số của hàm tạo.

Chỉ định một hàm tạo trừu tượng (do đó làm cho lớp trừu tượng). Các lớp có nguồn gốc phải triển khai hàm tạo này với chữ ký cụ thể của nó để mất trạng thái trừu tượng.

Tôi không thấy cách nào khác để chỉ định chữ ký hàm khởi tạo bắt buộc (hãy giúp tôi nếu bạn làm).

+3

Làm cho hàm tạo 'protected' vẫn cho phép bạn chỉ định tham số constructor trông như thế nào". – Raedwald

+0

đúng, nhưng làm như vậy yêu cầu lớp dẫn xuất gọi super() hoặc rủi ro thiếu các bước init có thể xảy ra. Tóm tắt làm rõ đây là chữ ký duy nhất, không thực hiện. - Sẽ tốt nhất nếu các giao diện được phép chỉ định chữ ký hàm tạo. Nhưng kể từ khi họ không, tôi xem xét các lớp trừu tượng điều tốt nhất tiếp theo. – foo

+3

Bạn không thể tránh gọi 'super'. Nó được gọi là ngầm nếu bạn không gọi nó một cách rõ ràng. – Raedwald

0

Khả năng hiển thị cũng ảnh hưởng đến những gì được hiển thị trong javadoc (nếu được chọn để loại trừ các mức hiển thị nhất định). Vì nó không quan trọng bằng cách khác, đó có thể là một cách sử dụng cho một nhà xây dựng công cộng của một lớp trừu tượng.

Nếu bạn không cung cấp hàm tạo, thì hàm khởi tạo mặc định là công khai nếu lớp là công khai. Tùy chọn dễ nhất là để cho phép điều đó, thay vì buộc các nhà xây dựng được bảo vệ.

Trong ý nghĩa đó, câu hỏi ngược lại có thể làm rõ: tại sao chúng không buộc các nhà xây dựng được bảo vệ trong các lớp trừu tượng? Bởi vì các nhà xây dựng công cộng sẽ không thay đổi bất cứ điều gì, do đó, nó sẽ chỉ mất thời gian và thêm phức tạp.