2010-10-08 55 views
7

Mở rộng giao diện chỉ cần thêm các hoạt động bổ sung được xác định trong bất kỳ trình triển khai nào và không thể phá vỡ bất kỳ triển khai hiện có nào (không giống như mở rộng một lớp). Nhưng nó có thể thay đổi (CHỈNH SỬA 3 NHỮNG BÀI HÁT) và do đó giá trị PERCIEVED của các hằng số (CHỈNH SỬA 2 NHƯ THẾ NÀO THEO CÁC LOẠI THỰC HIỆN).Tại sao không có giao diện cuối cùng trong Java?

Ví dụ, sau đây:

interface A { 
    int TEST = 6; 
} 

interface B extends A { 
    int TEST = 7; 
} 

public class InterfacesTest implements B { 
    public static void main(final String[] args) { 
    System.out.println(TEST); 
    } 
} 

sản lượng 7, khi có lẽ mục đích của giao diện A là bất kỳ thực hiện A chứa một lĩnh vực có giá trị từ test 6.

Nếu A là được tuyên bố cuối cùng chúng tôi có thể đảm bảo tất cả việc triển khai A đều thấy cùng giá trị test.

Vì vậy, có ai hiểu tại sao điều này là không thể?

  • P.S .: Điều này là KHÔNG một bản sao của this question, tôi biết họ không thể là cuối cùng, tôi quan tâm đến những suy nghĩ đằng sau những quyết định thiết kế dẫn đến kết cục này.

  • P.P.S .: Tôi hiểu các hằng số trong các giao diện thường là ý tưởng tồi, không phải là vấn đề ở đây.

EDIT: Vui lòng kiểm tra lịch sử sửa đổi, tiêu đề của câu hỏi này đã được chỉnh sửa theo một cách mà không phản ánh ý định của câu hỏi. Xin lỗi mọi người đã trả lời câu hỏi mà tôi không hỏi. Có, các trường giao diện ngầm hoàn toàn công khai tĩnh, tiếc là đó không phải là những gì tôi quan tâm cả.

EDIT 2 Để được hoàn toàn rõ ràng: câu hỏi này là về việc tại sao có thể không phải là một khối giao diện giao diện khác từ mở rộng nó (bằng cách thức hoặc một số tương đương).

+4

Câu trả lời là họ đang * luôn * 'final'. Chúng cũng luôn là 'tĩnh'. – jbindel

+0

Và các trường trong giao diện luôn là _public_ quá –

+1

Downvote. Câu hỏi dựa trên một tiền đề giả. – EJP

Trả lời

5

Mục đích chính của giao diện không phải là một vùng chứa các hằng số, nó xác định một số API sẽ được thực hiện bởi các lớp cụ thể.

Và, từ một spec lang (9.4. Abstract method declarations):

Lưu ý rằng một phương pháp tuyên bố trong một giao diện không được công bố chính thức hoặc một lỗi thời gian biên dịch xảy ra.Tuy nhiên, một phương thức được khai báo trong một giao diện có thể được thực hiện bằng một phương thức được khai báo cuối cùng trong một lớp thực hiện giao diện.

+0

Không nói về các phương pháp ở đây. Ngoài ra, tôi hiểu hằng số trong giao diện thường là một ý tưởng tồi, đó không phải là vấn đề ở đây. –

+2

Nhưng, nếu bạn có thể định nghĩa toàn bộ giao diện là 'final', nó có nghĩa là tất cả các phương thức của giao diện cũng là' final'. Và đó là bị cấm bởi spec một cách rõ ràng. –

+0

Ah, lần đầu tiên tôi không đọc được kết nối này. Bỏ chọn bình chọn. –

3

Như tôi đã hiểu, giao diện không được đặt ra các giới hạn về triển khai. Họ có nghĩa vụ phải xác định hợp đồng (API).
Từ thời điểm này, cả hai phương pháp doIt và hằng số TEST là các phần tử của API. Chúng ta biết cách sử dụng chúng, nhưng chúng ta không biết bên trong là gì.
Và cách thức chính xác doIt được triển khai trong InterfacesTest hoặc hằng số giá trị chính xác TEST có - chi tiết triển khai.

+0

Thật kỳ lạ khi nghĩ về giá trị của một hằng số như một chi tiết thực hiện, nhưng tôi cho rằng loại có ý nghĩa ... –

0

If A were to be declared final we could be assured all implementations of A see the same value of test.

có thể là bạn đã trả lời mình viết câu hỏi đó.

Bạn cũng không thể tạo ra một lớp trừu tượng cuối cùng, bởi vì có ý nghĩa nó phải được thực hiện, cùng một điều đi cho giao diện nó phải được thực hiện bởi một số lớp.

+0

Giao diện có thể hữu ích ngay cả khi không có lớp nào thực hiện chúng. Chúng có thể là các thùng chứa cho các hằng số. Đây có lẽ không phải là một ý tưởng tuyệt vời, nhưng nó không xa lạ. –

+0

Tắt khóa học, nhưng IMHO đây là một thực tế không tốt, nhà phát triển nên tránh. Vì lợi ích của ý tưởng nói rằng nếu bạn có thể làm điều gì đó không có nghĩa là bạn nên. –

11

final. Thực tế, nó là public static final ngay cả khi bạn không khai báo chúng. Những gì bạn đang làm không ghi đè biến cố định; bạn đang ẩn phiên bản giao diện của cha mẹ.

Kiểm tra xem, A.TEST không bị ghi đè. Nó vẫn là 6.

System.out.println (A.TEST);

+2

Hơn nữa, bạn có thể làm tương tự với các lớp học. Khai báo 'public static final int A = 6' trong parent và sau đó định nghĩa lại nó trong một lớp con là' public static final int A = 7'. Điều này được gọi là * ẩn * thay vì ghi đè vì phiên bản của lớp cha bị ẩn trừ khi bạn chỉ định nó. – jbindel

+0

Đây là một liên kết với các ví dụ về biến lớp ẩn. http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.3.3.1 – jbindel

+0

Tôi hiểu điều này. Nhưng giá trị của (một số thực hiện A) .TEST có thể khác nhau, và có lẽ đó không phải là ý định. –

2

Bạn có hai biến có tên TEST chứ không phải một biến. Không có ghi đè nào đang diễn ra. Ghi đè chỉ dành cho phương pháp.

+0

Ai đề cập đến việc ghi đè WAS đang diễn ra? Tôi đang bối rối những gì bạn đang trả lời. Vui lòng xem ví dụ và đọc lại câu hỏi, tiêu đề không may được chỉnh sửa ... –

+0

Bạn dường như giả định rằng có hai giá trị cho TEST, một giá trị mà A nhìn thấy và giá trị B thấy. Trong thực tế, có hai biến có tên là TEST. Giả định của bạn khiến tôi đoán rằng bạn nghĩ rằng B ghi đè A.TEST. InterfacesTest sử dụng TEST B như được định nghĩa trong JLS. –

1

phương pháp cuối cùng không thể được ghi đè lên.

cuối cùng ngăn không cho trường bị thay đổi, nhưng không ngăn trường bị ẩn. Lưu ý: Bạn không thể ghi đè trường.

Trong trường hợp A.TEST của bạn bị ẩn bởi B.TEST tuy nhiên

System.out.println(A.TEST); 
System.out.println(B.TEST); 

sẽ in

6 
7 
+0

Phải, tôi hiểu điều đó. Tuy nhiên, mối quan tâm của tôi là giá trị của InterfacesTEST.TEST. –

+0

Giao diệnTest mở rộng B và không ẩn nó để TEST là 7. –

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