2016-08-10 11 views
6

W Swift można utworzyć rozszerzenie istniejącej klasy, aby w razie potrzeby dodać dodatkowe funkcje do istniejącej klasy. Pomaga to również uniknąć tworzenia podklasy istniejącej klasy.Czy Java obsługuje rozszerzenia klas podobne do Swift?

Zastanawiam się, czy istnieje podobna funkcja w Javie? czy jest to jedyny sposób na dodanie dodatkowych metod do istniejącej klasy Java, aby utworzyć podklasę istniejącej klasy?

+2

Nie w Javie. Jednak nie wszyscy są zadowoleni z tego słowa w Scali. Może to utrudniać czytelność, łatwość konserwacji. Zazwyczaj tworzy się klasę z funkcjami, takimi jak XxxUtils lub Xxx. Dziedziczenie ma tam swoje własne problemy (klasy końcowe, wymuszona przestarzałość starego kodu, centralizm = tylko jeden punkt rozszerzenia). –

Odpowiedz

5

Nie, vanilla Java nie ma dostępnych metod rozszerzenia. Jednak Lombok dodaje wiele przydatnych funkcji - w tym składni metod rozszerzeń - dzięki swoim adnotacjom i generowaniu kodu bajtowego.

Możesz użyć jego adnotacji @ExtensionMethod, aby "przekonwertować" istniejące metody statyczne na metody rozszerzeń. Pierwszy parametr metod statycznych w zasadzie staje się this. Na przykład, czy jest to prawidłowy Lombok podwyższonym kod Java:

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(); 
    } 
} 

Zauważ, że rozszerzenie metod Lombok może być „wywoływane” na zerowych obiektów - tak długo, jak metoda statyczna jest null-safe, NullPointerException nie zostanie wyrzucony , ponieważ jest to w zasadzie przetłumaczone na statyczne wywołanie metody. Tak - to sprowadza się do składni cukru, ale myślę, że jest to jeszcze bardziej czytelne niż zwykłe wywołania metod statycznych.

Poza tym, możesz użyć innego języka JVM z operacją Java, jeśli jest to w twoim projekcie. Na przykład Kotlin jest dostarczany z extension methods functionality, a także z niektórymi przydatnymi rozszerzeniami już zdefiniowanymi w bibliotece standardowej. Oto Kotlin and Lombok comparison.

1

Prawdopodobnie najbliżej pasuje Decorator Pattern. Używa interfejsu do utrzymywania kompatybilności typów i kompozycji w celu ulepszenia funkcji istniejącej klasy. Nie jest to ta sama zasada, co opisywana, ale może służyć temu samemu celowi.

2

Można to zrobić w innych językach dla JVM, takich jak Scala, Groovy lub Zamknięcie.

Na przykład w Groovy:

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

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

W Scali można użyć implicit conversions:

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

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

"foo".prefix // returns "prefix_foo" 

Proszę spojrzeć na this article.

ważna uwaga jest taka, że ​​kod źródłowy Groovy/Scala przeznaczone do kompilacji do kodu bajtowego Java, aby uzyskane klasy mogły być używane w kodzie Java.

+1

Poza tym Lombok ma trochę magii wewnętrznie, ale jest to Java, więc mówiąc, że jej "niemożliwe" nie jest dokładnie prawdziwe. – JustACluelessNewbie

+1

ok, dzięki za uwagi, właśnie zaktualizowałem mój awser. –

+0

Przykład Scala powinien prawdopodobnie używać 'niejawnej klasy', która 'extends AnyVal' – Clashsoft

Powiązane problemy