2010-05-16 18 views
10

Trường hợp sử dụng có hai nhà thầu có cùng chữ ký là gì?Tại sao bạn có hai nhà thầu có cùng chữ ký?

Chỉnh sửa: Bạn không thể làm điều đó trong Java vì Java hiệu quả cho biết bạn cần nhà máy tĩnh. Nhưng tôi đã tự hỏi tại sao bạn cần phải làm điều đó ngay từ đầu.

+1

erm, bạn không thể, phải không? –

+5

Đầu tiên, bạn có thể cho chúng tôi thấy một ví dụ biên dịch không? –

+0

Đối với hồ sơ, bạn có nghĩa là hai nhà xây dựng * trong cùng một lớp * với cùng một chữ ký không? – harpo

Trả lời

15

Lý do bạn muốn nghĩ bạn muốn thực hiện điều này là bạn đã tìm thấy chính mình trong một tình huống mà biến kiểu không đủ ngữ cảnh.

Ví dụ, tôi có thể đánh lừa bản thân mình nghĩ rằng tôi cần phải cung cấp cho hai lớp xây dựng của tôi: một trong đó hoạt động bằng X và Y, và một theo độ và radian. Cả hai có thể được biểu diễn dưới dạng float.

Vì vậy, tôi nghĩ rằng tôi cần hai nhà thầu có chữ ký giống hệt nhau (float, float).

Dr.Bloch chỉ ra rằng nó tốt hơn để thực hiện các phương pháp nhà máy:


    public static Point newPointByDegreesAndRadians (float degrees, float radians); 
    public static Point newPointByXandY (float x, float y); 

Ngẫu nhiên, khác thay thế cho phương pháp nhà máy là để tạo ra các loại mà mang bối cảnh đó là mất tích từ kiểu dữ liệu, như thế này:


    public class CoordinatesXY { 
     float X; 
     float Y; 
     ... 
    } 
    public class CoordinatesDegreesRadians { 
     float degrees; 
     float radians; 
     ... 
    } 
    public Point (CoordinatesXY coordinates) { ... } 
    public Point (CoordinatesDegreesRadians coordinates) { ... } 

Cho dù bạn nghĩ rằng điều này là rõ ràng hơn so với các phương pháp nhà máy là một vấn đề của hương vị. Đối với trường hợp cụ thể này, cảm giác của riêng tôi là hai lớp tọa độ chỉ được sử dụng nếu thiết kế của bạn làm cho tọa độ hữu ích theo cách riêng của chúng, tách biệt khỏi một điểm tại các tọa độ đó.

5

Lớp không thể có hai hàm tạo có cùng chữ ký.

From the JLS:

8.8.2 Constructor Chữ ký

Đó là một lỗi thời gian biên dịch để khai báo hai nhà xây dựng với ghi đè tương đương (§8.4.2) chữ ký trong một lớp học. Đó là một lỗi biên dịch thời gian để khai báo hai hàm tạo có chữ ký có cùng xóa (§4.6) trong một lớp.

+2

Tôi biết rằng Java không cho phép điều đó. Đây là lý do tại sao chúng ta cần nhà máy tĩnh. Nhưng tại sao chúng ta cần phải tạo ra các nhà thầu khác nhau tại chỗ. – unj2

2

Bạn sẽ không làm như vậy và bạn cũng không thể. Nó sẽ không biên dịch các tệp lớp thành bytecode vì không có cách nào để chương trình phân biệt giữa chúng để quyết định cái nào sẽ sử dụng.

+0

Trên thực tế, quá trình phân giải quá tải xảy ra vào thời gian biên dịch, vì vậy chương trình sẽ không bao giờ tồn tại khi cố tìm đúng nhà xây dựng. – Joey

+4

Đó không phải là những gì tôi đã nói, hay tôi chỉ hiểu lầm bạn? – AaronM

1

@kunjaan - có rất ít trường hợp sử dụng cho ý tưởng như vậy ngay cả khi có một cách hợp lệ về mặt kỹ thuật để làm điều đó (trong Java không có - xem câu trả lời khác).

Một trường hợp sử dụng có thể sẽ được triển khai khác nhau dựa trên một số điều kiện bên ngoài - ví dụ, một nhà xây dựng có thể cấp phát bộ nhớ nhất định nếu nó không có sẵn hoặc sử dụng lại bộ nhớ đó từ một số nhóm chung trong chương trình. đã có sẵn.

Một ví dụ khác về điều đó sẽ là một hàm tạo sẽ thực hiện một số điều nhất định bằng cách sử dụng cuộc gọi hệ thống hiệu quả hơn nếu kiến ​​trúc hiện tại hỗ trợ cuộc gọi hệ thống đó. BTW, cả hai ví dụ này là một chút khó khăn hơn để tưởng tượng trong Java nhưng dễ dàng hơn để tưởng tượng trong C++ -land, nhưng bạn sẽ có được ý tưởng tổng thể hy vọng. Trong một trong hai trường hợp, điều này thực sự được mã hóa bằng cách có một nhà máy như bạn đã đề cập, HOẶC có một nhà xây dựng duy nhất, thực hiện một số loại quyết định dựa trên môi trường và gọi phương thức trợ giúp với các chữ ký khác nhau để thực sự khởi tạo cần thiết đó là phụ thuộc thực hiện, ví dụ (Trong giả, ngôn ngữ độc lập)

function helper_initializer(signature for case 1) { 

} 
function helper_initializer(signature for case 2) { 

} 
function constructor() { 
    // constructor logic here 
    if (environmental_consdition() == 1) { 
     this->helper_initializer(signature for case 1); 
    } else { 
     this->helper_initializer(signature for case 2); 
    } 
} 
3

Để trả lời câu hỏi được chỉnh sửa mới của bạn, ý định sẽ là nếu bạn có một lớp có thể có hai hành động khác nhau về mặt logic nhưng điều đó xảy ra giống như chữ ký.

Ví dụ: giả sử bạn có lớp Người quan tâm đến tên và nơi sinh của ai đó.

public Person(String name) { ... } 
public Person(String placeOfBirth) { ... } 

Rõ ràng, điều này không hiệu quả.

Bạn phải sử dụng một nhà máy:

public static Person personWithName(String name) { ... } 
public static Person personFromPlace(String placeOfBirth) { ... } 

Rõ ràng là một ví dụ giả tạo, nhưng đó là ý tưởng chung ...

+0

Đây là một ví dụ tuyệt vời. – unj2

11

Lý do bạn sẽ muốn có hai (hoặc nhiều hơn) nhà xây dựng với cùng một chữ ký là kiểu dữ liệu không đồng nghĩa với ý nghĩa.

Ví dụ đơn giản là lớp Line.

Dưới đây là một constructor: public class Line(double x1, double y1, double x2, double y2)

Đây là một: public class Line(double x1, double y1, double angle, double distance)

Các nhà xây dựng đầu tiên xác định hai điểm cuối của một dòng. Hàm khởi tạo thứ hai định nghĩa một điểm kết thúc và góc và khoảng cách đến điểm kết thúc thứ hai.

Java không thể phân biệt giữa hai hàm tạo lớp Dòng, đúng. Nhưng có những lý do tốt cho 2 hoặc nhiều nhà thầu để có chữ ký giống nhau.

+1

+1 - câu đầu tiên là điểm mấu chốt. –

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