Szukam zaimplementowania funkcjonalności na liście obiektów, tak jak w C # przy użyciu metody rozszerzenia.
Coś takiego:
List<DataObject> list;
// ... List initialization.
list.getData(id);
Jak to zrobić w Javie?
java
extension-methods
Fabio Milheiro
źródło
źródło
Odpowiedzi:
Java nie obsługuje metod rozszerzających.
Zamiast tego możesz utworzyć zwykłą metodę statyczną lub napisać własną klasę.
źródło
Metody rozszerzeń to nie tylko metoda statyczna, a nie tylko wygodna składnia, w rzeczywistości są one dość potężnym narzędziem. Najważniejsza jest możliwość nadpisywania różnych metod opartych na instancji różnych parametrów generycznych. Jest to podobne do klas typu Haskella i faktycznie wygląda na to, że są w C #, aby obsługiwać monady C # (tj. LINQ). Nawet porzucając składnię LINQ, nadal nie wiem, jak zaimplementować podobne interfejsy w Javie.
I nie sądzę, aby można je było zaimplementować w Javie, ze względu na semantykę parametrów generycznych w Javie.
źródło
Projekt Lombok zawiera adnotację,
@ExtensionMethod
której można użyć do osiągnięcia żądanej funkcjonalności.źródło
java.lang.String
.. Demonstracja: http://manifold.systems/images/ExtensionMethod.mp4Technicznie rzecz biorąc, rozszerzenia C # nie mają odpowiednika w Javie. Ale jeśli chcesz zaimplementować takie funkcje, aby uzyskać bardziej przejrzysty kod i łatwość konserwacji, musisz użyć struktury Manifold.
źródło
Język XTend - który jest super zestawem języków Java i kompiluje się do kodu źródłowego Java 1 - obsługuje to.
źródło
Manifold udostępnia Javę z metodami rozszerzeń w stylu C # i kilkoma innymi funkcjami. W przeciwieństwie do innych narzędzi, Manifold nie ma ograniczeń i nie cierpi z powodu problemów z typami ogólnymi, lambdami, IDE itp. Manifold zapewnia kilka innych funkcji, takich jak niestandardowe typy w stylu F # , strukturalne interfejsy w stylu TypeScript i typy expando w stylu JavaScript .
Dodatkowo IntelliJ zapewnia kompleksową obsługę Manifolda poprzez wtyczkę Manifold .
Manifold to projekt open source dostępny na github .
źródło
Inną opcją jest użycie klas ForwardingXXX z biblioteki google-guava.
źródło
Java nie ma takiej funkcji. Zamiast tego możesz utworzyć zwykłą podklasę swojej implementacji listy lub utworzyć anonimową klasę wewnętrzną:
Problem polega na wywołaniu tej metody. Możesz to zrobić „na miejscu”:
źródło
Wygląda na to jest jakaś mała szansa, że Defender (tj Metody Metody domyślne) może uczynić go Java 8. Jednakże o ile mi ich zrozumieć, pozwalają one tylko autor od An
interface
wstecznie przedłużyć go, a nie arbitralnych użytkowników.Defender Methods + Interface Injection byłby wtedy w stanie w pełni zaimplementować metody rozszerzeń w stylu C #, ale AFAICS, Interface Injection nie jest jeszcze na mapie drogowej Java 8.
źródło
Trochę za późno na imprezę w tej sprawie, ale na wypadek, gdyby ktoś uznał to za przydatne, właśnie utworzyłem podklasę:
źródło
Możemy zasymulować implementację metod rozszerzających C # w Javie, używając domyślnej implementacji metody dostępnej od Java 8. Zaczynamy od zdefiniowania interfejsu, który pozwoli nam na dostęp do obiektu wsparcia za pomocą metody base (), na przykład:
Zwracamy wartość null, ponieważ interfejsy nie mogą mieć stanu, ale należy to później naprawić za pośrednictwem serwera proxy.
Twórca rozszerzeń musiałby rozszerzyć ten interfejs o nowy interfejs zawierający metody rozszerzające. Powiedzmy, że chcemy dodać konsumenta forEach do interfejsu List:
Ponieważ rozszerzamy interfejs Extension, możemy wywołać metodę base () wewnątrz naszej metody rozszerzenia, aby uzyskać dostęp do obiektu wsparcia, do którego się podłączamy.
Interfejs Extension musi posiadać metodę fabryczną, która utworzy rozszerzenie danego obiektu wsparcia:
Tworzymy proxy, które implementuje interfejs rozszerzenia i cały interfejs zaimplementowany przez typ obiektu wsparcia. Procedura obsługi wywołań przekazana proxy mogłaby wysłać wszystkie wywołania do obiektu wsparcia, z wyjątkiem metody „podstawowej”, która musi zwrócić obiekt wsparcia, w przeciwnym razie jej domyślna implementacja zwraca wartość null:
Następnie możemy użyć metody Extension.create (), aby dołączyć interfejs zawierający metodę rozszerzenia do obiektu pomocniczego. Rezultatem jest obiekt, który można rzutować na interfejs rozszerzenia, za pomocą którego nadal możemy uzyskać dostęp do obiektu pomocniczego wywołującego metodę base (). Mając referencję rzuconą na interfejs rozszerzenia, możemy teraz bezpiecznie wywołać metody rozszerzające, które mogą mieć dostęp do obiektu wsparcia, dzięki czemu możemy teraz dołączyć nowe metody do istniejącego obiektu, ale nie do jego definiującego typu:
Jest to więc sposób, w jaki możemy zasymulować możliwość rozszerzania obiektów w Javie poprzez dodawanie do nich nowych kontraktów, które pozwalają nam wywoływać dodatkowe metody na danych obiektach.
Poniżej znajduje się kod interfejsu rozszerzenia:
źródło
Można by wykorzystać wzorzec projektowania obiektowego dekoratora . Przykładem tego wzorca używanego w standardowej bibliotece Javy byłby DataOutputStream .
Oto kod rozszerzający funkcjonalność listy:
PS Jestem wielkim fanem Kotlina . Ma metody rozszerzające, a także działa na JVM.
źródło
Możesz stworzyć metodę rozszerzenia / pomocnika podobną do C #, implementując (RE) interfejs Collections i dodając - przykład dla Java Collection:
źródło
Java
8 obsługuje teraz metody domyślne , które są podobne doC#
metod rozszerzających.źródło