2014-07-07 24 views
18

Trong java 8, một lớp trừu tượng chỉ có một phương thức trừu tượng không phải là giao diện chức năng (JSR 335).Lớp trừu tượng làm giao diện chức năng

interface Đây là một giao diện chức năng:

public interface MyFunctionalInterface { 
    public abstract void myAbstractMethod(); 
    public default void method() { 
     myAbstractMethod(); 
    } 
} 

nhưng abstract class đây không phải là:

public abstract class MyFunctionalAbstractClass { 
    public abstract void myAbstractMethod(); 
    public void method() { 
     myAbstractMethod(); 
    } 
} 

Vì vậy, tôi không thể sử dụng lớp trừu tượng như một mục tiêu cho một biểu thức lambda và tham khảo phương pháp .

public class Lambdas { 
    public static void main(String[] args) { 
     MyFunctionalAbstractClass functionalAbstractClass =() -> {}; 
    } 
} 

Lỗi biên dịch là: The target type of this expression must be a functional interface.

Tại sao các nhà thiết kế ngôn ngữ áp đặt hạn chế này?

+0

Câu hỏi hay ... khả năng tương thích có thể? – Mena

+0

Điều này đã được yêu cầu và trả lời trước đây ... lý do chính là tính linh hoạt trong tương lai, nơi mà lambdas được dự kiến ​​sẽ rất khác với các phiên bản lớp. –

+6

Ở đây, đọc nó [từ miệng ngựa] (http://mail.openjdk.java.net/pipermail/lambda-dev/2013-March/008441.html). –

Trả lời

16

Đây là một chủ đề quan trọng kể từ khi thành lập dự án Lambda và đã nhận được rất nhiều suy nghĩ. Brian Goetz, kiến ​​trúc sư trưởng ngôn ngữ Java, hỗ trợ mạnh mẽ chế độ xem lambda dưới dạng hàm , không phải là đối tượng . Trích dẫn:

Tôi tin rằng hướng tốt nhất để phát triển Java là khuyến khích một kiểu lập trình chức năng hơn. Vai trò của Lambda là chủ yếu để hỗ trợ sự phát triển và tiêu thụ hơn thư viện chức năng giống như

Tôi lạc quan về tương lai của Java, nhưng để di chuyển về phía trước thỉnh thoảng chúng ta phải buông bỏ một số ý tưởng thoải mái. Các hàm lambdas sẽ mở ra cửa ra vào. Lambdas-là-đối tượng đóng cửa chúng. Chúng tôi muốn thấy những cánh cửa đó mở ra .

Here là một liên kết đến nguồn của báo giá và here là bài gần đây của Brian mà nhắc lại những điểm phylosophical cùng và khẳng định chúng với bổ sung, lý lẽ thực tế hơn:

Làm mô hình đơn giản hơn mở cửa tất cả các loại tối ưu hóa VM . (Danh tính bỏ sót là chìa khóa ở đây.) Chức năng là giá trị. Việc mô hình hóa chúng làm đối tượng làm cho chúng trở nên nặng hơn và phức tạp hơn, so với chúng cần thiết.

Trước khi ném trường hợp sử dụng này dưới xe buýt, chúng tôi đã thực hiện phân tích số liệu để tìm mức độ thường xuyên SAM lớp được sử dụng so với giao diện SAM. Chúng tôi thấy rằng trong kho văn bản đó, chỉ có 3% ứng cử viên lambda trường hợp lớp bên trong có lớp trừu tượng làm mục tiêu của họ. Và hầu hết các số chúng đều tuân theo các phép tái cấu trúc đơn giản, nơi bạn thêm một nhà xây dựng/nhà máy chấp nhận một lambda được nhắm mục tiêu theo giao diện.

+9

Tôi sẽ chỉ thêm rằng đây là một trong những chủ đề được tranh luận sôi nổi nhất trong giai đoạn đầu của JSR-335. Khi chúng tôi lần đầu tiên đề xuất quy tắc "chỉ giao diện", điều đó có vẻ nguy hiểm. Nhưng vì điều này đã có nhiều năm để giải quyết, tôi hoàn toàn tin rằng chúng tôi đã làm đúng. Chúng tôi đã đạt được sự đơn giản và linh hoạt đáng kể (tích luỹ cho tất cả người dùng dưới dạng hiệu suất tốt hơn và phát triển ngôn ngữ trong tương lai linh hoạt hơn) vì đã giảm một số trường hợp sử dụng ở góc. –

+3

Vâng, trên thực tế, tôi coi khía cạnh cụ thể đó là mang lại giá trị cao nhất tổng thể của dự án Lambda cho Java. Có vẻ như "đúng" ở mức độ sâu, "rạng rỡ" hơn nhiều tính năng khác mà chúng ta đã thấy trong sự tiến hóa của ngôn ngữ --- và đặt chân vào các hướng mới, thú vị cho tương lai của Java. –

+0

Tôi không thấy Brian Goetz cung cấp bất kỳ lời khuyên nào ở đây. Chỉ là một vài WORDS vô nghĩa. Lambdas là cú pháp cho các lớp bên trong vô danh. Vậy tại sao thêm cay đắng vào đường? – Dims

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