2013-07-08 30 views
6

Tôi bắt gặp một kịch bản, nơi tôi cần một nhà xây dựng công cộng và tư nhân. Một hàm tạo riêng là cần thiết để thiết lập trường riêng có kiểu là lớp bên trong riêng. Điều này có bị che khuất hay không được khuyến khích? Khác một giải pháp tốt hơn cho một kịch bản được liệt kê dưới đây là gì?Một lớp học có cả nhà xây dựng công cộng và tư nhân không?

Vui lòng đọc nhận xét, hỗ trợ câu hỏi của tôi có ý nghĩa hơn. Cảm ơn,

public class CopyTree { 
    private TreeNode root; 

    public Copytree() { } 

    // private CopyTree(TreeNode root) { this.root = root; } 

    private static class TreeNode { 
     TreeNode left; 
     TreeNode right; 
     Integer element; 
     TreeNode(TreeNode left, TreeNode right, Integer element) { 
      this.left = left; 
      this.right = right; 
      this.element = element; 
    } 
} 

public CopyTree copyTree() { 
    CopyTree ct = new CopyTree(); 
    ct.root = copyTree(root); // <---- QUESTION: Any cleaner solution ?? 
    // cleaner solution appears to be a private constructor 
    // eg: CopyTree ct = new CopyTree(copyTree(root)); But can public and private constructor  coexist together ? 
    return ct; 
} 

private TreeNode copyTree(TreeNode binaryTree) { 
    TreeNode copy = null; 
    if (binaryTree != null) { 
     copy = new TreeNode(null, null, binaryTree.element); 
     copy.left = copyTree(binaryTree.left); 
     copy.right = copyTree(binaryTree.right); 
    } 
    return copy; 
} 
+2

Kiểm tra điều này: http://stackoverflow.com/a/11360712/1544069 – ritesh

+1

Tại sao bạn không chấp nhận câu trả lời? Tất cả họ đều dành thời gian của họ để trả lời bài viết của bạn vì vậy đó là ít nhất bạn có thể làm để đổi lại. C'mon;) – Andy

+1

Chắc chắn, tôi xin lỗi. Sẽ lưu ý và cảm ơn toàn thể cộng đồng vì đã giúp đỡ, Ngoài ra cảm ơn vì đã chú ý đến điều này. – JavaDeveloper

Trả lời

0

Lớp học có thể có cả nhà xây dựng công cộng và tư nhân?

Có, điều đó là có thể.

Một hàm tạo riêng là cần thiết để đặt trường riêng tư có loại là lớp bên trong riêng tư. Điều này được khuyến khích hay nản chí?

Tùy thuộc vào tình huống. Cho dù bạn muốn lớp khác để khởi tạo trạng thái của đối tượng của bạn hay không. Ở đây tôi nghĩ bạn đã tạo ra lớp CopyTree để trả về bản sao của Tree là một lớp riêng. Vì vậy, lớp TreeNode sẽ được đóng gói, do đó nó để lại cho bạn tùy chọn sử dụng thành phần bắt giữ của hàm tạo riêng.

giải pháp tốt hơn cho kịch bản được liệt kê bên dưới là gì?

Trong chế độ xem của tôi, thành phần chụp người xây dựng riêng tư là giải pháp tốt hơn.

Để biết thêm thông tin:

bạn có thể tìm kiếm private constructor capture idiom.

Một ví dụ được đưa ra trong Solution 53 của Java Puzzlers:

Puzzle 53: Bạn Thing của bạn

Bây giờ đến lượt của bạn để viết một số mã. Giả sử rằng bạn có một lớp thư viện gọi Thing có duy nhất constructor có một tham số int:

public class Thing {  
    public Thing(int i) { ... } 
     ... 
    } 

A Thing dụ cung cấp không có cách nào để có được những giá trị của tham số constructor của nó. Bởi vì Thing là một lớp thư viện, bạn không có quyền truy cập vào nội bộ của nó, và bạn không thể sửa đổi nó. Giả sử rằng bạn muốn viết một lớp con được gọi là MyThing, với một hàm tạo tính toán tham số cho hàm tạo siêu lớp bằng cách gọi phương thức SomeOtherClass.func(). Giá trị được trả về bởi phương thức này thay đổi không thể đoán trước từ cuộc gọi đến cuộc gọi. Cuối cùng, giả sử rằng bạn muốn lưu trữ giá trị đã được truyền cho hàm tạo lớp bậc trên trong trường cá thể cuối cùng của lớp con để sử dụng sau này. Đây là mã mà bạn muốn một cách tự nhiên viết:

public class MyThing extends Thing { 
    private final int arg; 
    public MyThing() { 
     super(arg = SomeOtherClass.func()); 
     ... 
    } 
    ... 
} 

Thật không may, nó không phải là hợp pháp.Nếu bạn cố gắng để biên dịch nó, bạn sẽ nhận được một thông báo lỗi mà trông giống như sau:

MyThing.java: 
    can't reference arg before supertype constructor has been called 
     super(arg = SomeOtherClass.func()); 
       ^

Làm thế nào bạn có thể viết lại MyThing để đạt được hiệu quả mong muốn? Hàm tạo MyThing() phải là luồng an toàn: Nhiều luồng có thể gọi đồng thời.

Giải pháp 53: Làm Thing của bạn

Bạn có thể thử để stash kết quả của sự thỉnh nguyện SomeOtherClass.func() trong một lĩnh vực tĩnh trước khi gọi các nhà xây dựng Thing. Giải pháp này là khả thi nhưng khó xử. Để đạt được độ an toàn của luồng, bạn phải đồng bộ hóa quyền truy cập vào giá trị được lưu trữ, yêu cầu các xung đột không thể tưởng tượng được. Một số trong những mâu thuẫn này có thể tránh được bằng cách sử dụng một trường tĩnh địa phương (java.util.ThreadLocal), nhưng tồn tại một giải pháp tốt hơn nhiều. Giải pháp ưa thích vốn dĩ an toàn cũng như thanh lịch. Nó liên quan đến việc sử dụng thứ hai, xây dựng tư nhân trong MyThing:

public class MyThing extends Thing { 
    private final int arg; 

    public MyThing() { 
     this(SomeOtherClass.func()); 
    } 

    private MyThing(int i) { 
     super(i); 
     arg = i; 
    } 
} 

Giải pháp này sử dụng một constructor gọi thay thế. Tính năng này cho phép một hàm tạo trong một lớp kết nối với một hàm tạo khác trong cùng một lớp. Trong trường hợp này, các chuỗi MyThing() tới hàm tạo riêng MyThing (int), thực hiện khởi tạo cá thể bắt buộc. Trong hàm khởi tạo riêng, giá trị của biểu thức SomeOtherClass.func() đã được nắm bắt trong tham số i và có thể được lưu trữ trong tham số trường cuối cùng sau khi hàm tạo của lớp cha trả về.

0

Một lớp học có thể được ngăn không cho người dùng của nó khởi tạo bằng cách sử dụng các nhà thầu tư nhân .

đâu constructors tin rất hữu ích,

  • lớp chỉ chứa các phương pháp hữu ích tĩnh
  • lớp chỉ chứa các hằng số
  • loại enumerations an toàn
  • độc thân

đâu họ chứng minh được một bất lợi (không giới hạn ở các điểm dưới đây. Danh sách có thể tăng)

  • Các lớp không có nhà thầu công cộng hoặc được bảo vệ không được là được phân loại.
  • Chúng không dễ dàng phân biệt với các phương pháp tĩnh khác.
0

Bạn chỉ có thể sử dụng cả hàm tạo riêng và công khai theo cách sau. Nhưng bạn không thể sử dụng cả hai cho không có đối số constructor hoặc cùng một loại đối số.

public class MyClass { 
private MyClass(){ 

} 
public MyClass(int i){ 

} 
} 
0

Đánh giá từ mã nhận xét của bạn, bạn đã dùng thử và nó đã hoạt động. Vì vậy, tôi chỉ có thể xác nhận phát hiện của bạn: có, hàm tạo riêng có thể cùng tồn tại với công khai, và có, nó có vẻ như là một giải pháp tốt hơn vì việc khởi tạo nhiều hơn được thực hiện trước khi nhận tham chiếu đến đối tượng mới.

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