2016-08-10 25 views
6

Trong Swift, bạn có thể tạo phần mở rộng của lớp hiện có để thêm các hàm bổ sung vào lớp hiện có bất cứ khi nào nó cần. Điều này cũng giúp tránh tạo ra một lớp con của lớp hiện tại.Java có hỗ trợ các tiện ích mở rộng lớp giống Swift không?

Tôi đã tự hỏi liệu có một hàm tương tự tồn tại trong Java không? hoặc là cách duy nhất để thêm các phương thức bổ sung vào một lớp Java hiện có là tạo một lớp con của lớp hiện tại?

+2

Không có trong Java. Tuy nhiên không phải ai cũng hài lòng với điều đó trong Scala. Vì nó có thể cản trở khả năng đọc, bảo trì. Thông thường, người ta tạo một lớp với các hàm, như XxxUtils hoặc Xxx. Thừa kế có những vấn đề riêng của nó ở đó (các lớp cuối cùng, buộc phải vô dụng mã cũ, tập trung = chỉ là một điểm mở rộng). –

Trả lời

5

Không, vanilla Java không có các phương pháp mở rộng. Tuy nhiên, Lombok thêm nhiều tính năng hữu ích - bao gồm cả cú pháp phương thức mở rộng - nhờ chú thích và tạo mã byte.

Bạn có thể sử dụng các chú thích @ExtensionMethod để "chuyển đổi" phương pháp tĩnh hiện tại thành các phương pháp mở rộng. Tham số đầu tiên của các phương thức tĩnh về cơ bản trở thành this. Ví dụ, đây là một mã Java Lombok tăng cường hợp lệ:

import lombok.experimental.ExtensionMethod; 

@ExtensionMethod({java.util.Arrays.class, Extensions.class}) 
public class ExtensionMethodExample { 
    public String test() { 
    int[] intArray = {5, 3, 8, 2}; 
    intArray.sort(); 

    String iAmNull = null; 
    return iAmNull.or("hELlO, WORlD!".toTitleCase()); 
    } 
} 

class Extensions { 
    public static <T> T or(T obj, T ifNull) { 
    return obj != null ? obj : ifNull; 
    } 

    public static String toTitleCase(String in) { 
    if (in.isEmpty()) return in; 
    return "" + Character.toTitleCase(in.charAt(0)) + 
     in.substring(1).toLowerCase(); 
    } 
} 

Lưu ý rằng phương pháp khuyến nông Lombok có thể "gọi" trên các đối tượng null - miễn là phương pháp tĩnh là null-an toàn, NullPointerException sẽ không được ném , vì điều này về cơ bản được dịch sang gọi phương thức tĩnh. Có - nó đi xuống đường cú pháp, nhưng tôi đoán điều này vẫn còn dễ đọc hơn các phương thức tĩnh thông thường.

Ngoài ra, bạn có thể sử dụng một số ngôn ngữ JVM khác với khả năng tương tác Java, nếu đó là OK trong dự án của bạn. Ví dụ: Kotlin đi kèm với extension methods functionality, cũng như một số tiện ích mở rộng hữu ích đã được xác định trong thư viện chuẩn. Đây là Kotlin and Lombok comparison.

1

Có lẽ Decorator Pattern là trận đấu gần nhất. Nó sử dụng giao diện để duy trì tính tương thích và thành phần kiểu để tăng cường chức năng của lớp hiện tại. Nó không giống như nguyên tắc bạn mô tả nhưng có thể phục vụ cùng mục đích.

2

Có thể thực hiện bằng các ngôn ngữ khác cho JVM, như Scala, Groovy hoặc Đóng.

Ví dụ trong Groovy:

List.metaClass.printSize = { 
    println delegate.size() 
} 

[1,2,3].printSize() //prints 3 

Trong Scala bạn có thể sử dụng implicit conversions:

class PrefixedString(val s: String) { 
    def prefix = "prefix_" + s 
} 

implicit def stringToString(s: String) = new PrefixedString(s) 

"foo".prefix // returns "prefix_foo" 

hãy có một cái nhìn vào this article.

nhận xét quan trọng là mã nguồn Groovy/Scala dự định được biên dịch sang bytecode Java, để các lớp kết quả có thể được sử dụng trong mã Java.

+1

Bên cạnh đó, Lombok thực hiện một số phép thuật trong nội bộ, nhưng nó _is_ Java, do đó, nói rằng "không thể" của nó không chính xác là đúng. – JustACluelessNewbie

+1

ok, cảm ơn cho nhận xét, tôi chỉ cập nhật awser của tôi. –

+0

Ví dụ Scala có lẽ nên sử dụng một 'lớp ẩn' mà 'mở rộng AnyVal' – Clashsoft

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