2013-08-23 16 views
32

Jeśli mam na przykład klasę wraz z klasą pomocniczą, aby wykonać niektóre z jej funkcji, to ma sens, aby stała się klasą wewnętrzną.Kiedy używać klas wewnętrznych w Javie dla klas pomocniczych

public class Foo { 
     private FooHelper helper; 

     // constructor & any other logic 

     public void doSomeThing() { 
     helper.do(); 
     } 
    } 

    public class FooHelper { 
     public void do() { 
     // code 
     } 
    } 

W powyższym przypadku ma to sens, aby FooHelper jako wewnętrzna klasy? Przeprosiny, jeśli to brzmi głupio, ale jestem trochę zdezorientowany przypadkami użycia.

+0

http://javabeginnerstutorial.com/core-java-tutorial/inner-class/ –

+1

Generalnie dla uczestników akcji i kiedy nie chcesz ujawniać swojego połączenia innym. –

+0

@Vaibhav Jain dzięki za link, znam składnię, ale jestem trochę zdezorientowana, kiedy go użyć i czy jest jakikolwiek handel z offu – Hild

Odpowiedz

41

Tak, to ma doskonały sens, aby uczynić z niego klasę wewnętrzną. Jeśli żadne inne klasy tego nie potrzebują, uczyń to prywatnym. Jeśli nie wymaga wyłącznego dostępu do elementów klasy zewnętrznej, uczyń go statyczną klasą zagnieżdżoną, ponieważ wtedy będzie wymagać mniejszej ilości pamięci.

Zapoznaj się zalecenie the official tutorial -

Użyj non-statyczną klasę zagnieżdżony (lub wewnętrzną klasę), jeśli wymagają dostępu do pól niepublicznych i metod zamykającego instancji. Użyj klasę zagnieżdżoną , jeśli nie potrzebujesz tego dostępu.

+0

A kiedy powinna to być statyczna wewnętrzna klasa? czy istnieje jakaś różnica w stosunku do funkcjonalnego punktu widzenia? – Hild

+4

@Hild: 'Statyczna klasa zagnieżdżona' nie ma dostępu do elementów klasy otaczającej (chyba że jest statyczna). Jeśli to pasuje do Twojego wymagania, spraw, aby był statyczny. Natomiast niestatyczne klasy wewnętrzne mają pełny dostęp do członków klasy zamykającej. –

+0

@Hild zagnieżdżone klasy statyczne nie zawierają syntetycznych odwołań do ich klasy otaczającej. Więc jeśli nie masz konkretnych powodów, aby uczynić go niestatycznym, zawsze staraj się, aby była "statyczną klasą zagnieżdżoną". 'Statyczna klasa wewnętrzna' jest technicznie niewłaściwą terminologią. – Geek

10

Jeśli uważasz, że FooHelper będzie wcale nie być przydatna dla innych klas niż Foo, to ma sens, aby to samo privatewewnętrznej klasy z Foo. Jeden przykład tego rodzaju projektu można znaleźć w HashMap, gdzie definiuje prywatną klasę wewnętrzną. Inaczej ma ona instancję private wygląda dobrze.

1

Klasy wewnętrzne mają sens, gdy są małe i nie wymagają nazw. Słuchacze w GUI to klasyczne przykłady, w których mają sens.

Jeśli zajęcia są duże i ważne, należy je nazwać i umieścić w osobnym pliku.

Klasy słuchaczy w zwykłych przykładach GUI robią jedną drobną rzecz, zwykle po prostu wysyłają do jakiejś innej funkcji do prawdziwej pracy.

Często używam klas zagnieżdżonych statycznie (które nie są technicznie klasami wewnętrznymi) dla klas, które są używane tylko w kontekście innej klasy - dobrym tego przykładem jest Map.Entry. Jest używany tylko w połączeniu z Mapą, więc posiadanie definicji Entry jako części interfejsu Map ma sens organizacyjny.

Zasadniczo nie używam innych typów klas zagnieżdżonych, takich jak niestatyczne klasy członkowskie i klasy lokalne. Ale czasami okazują się przydatne. Aby uzyskać dobry przykład legalnego użytkowania klas członków, zobacz kod źródłowy dla LinkedList.ListItr. Jest to prywatna klasa wewnętrzna, której celem jest zapewnienie implementacji ListIterator dla LinkedList. Aby to zrobić, dobrze jest mieć dostęp do prywatnych danych wewnątrz listy LinkedList. Aby osiągnąć to przy użyciu jedynie klas najwyższego poziomu, konieczne byłoby ujawnienie większej liczby publicznych metod w LinkedList, aby umożliwić ListIteratorowi uzyskanie podstawowej implementacji listy LinkedList. Zamiast tego, używanie klasy wewnętrznej pozwala programowi LinkedList zachować jego implementację jako prywatną, tak jak być powinno.

+0

Przepraszam, jestem wiecznym nowicjuszem i chciałbym wyjaśnienia, ponieważ nie widzę miejsca wewnętrznego w świecie OOP: Mogą one uzyskać dostęp do ** prywatni ** członkowie zewnętrznej klasy ... Nie można ich ponownie użyć, tylko wklejając kopie ... Uczyń kod brzydszym i trudniejszym do odczytania i zachowaniem ... (ciąg dalszy) – inigoD

+0

I rozumiem tylko Twoją argumentację, aby nie ujawniać wielu publicznych metod podczas optymalizacji aplikacji, ale nie widzisz, co jest sensowne w GUI: Wzorzec słuchacza daje możliwość zmiany zachowania elementu (co zrobić w przypadku zdarzenia "kliknij" przycisku na przykład) w czasie wykonywania. Jeśli słuchacz jest wewnętrzną klasą, zwykle oznacza to, że naprawdę nie potrzebowałeś możliwości słuchacza: chciałaś użyć metody "onClick", której nigdy nie użyjesz ponownie (jak to zwykle bywa w Androidzie). – inigoD

+0

@eddieferetro 1 przypadek użycia nie wystawia całego obiektu, gdy ma być użyty w określonej klasie. – Hild

0

Tak, zaletą korzystania z wewnętrznej klasy jest możliwość dostępu do członków klasy zewnętrznej. W twoim przypadku, jeśli uważasz, że twoja FooHelper nie może być używana przez żadną inną klasę, możesz uczynić ją wewnętrzną klasą.

Aby sprawdzić użyteczność klasy wewnętrznej, przejrzyj przykłady AWT. Anonimowe klasy wewnętrzne są szeroko stosowane w procedurach obsługi zdarzeń.

0

Co to jest zakres Foo? Kiedy Foo jest z własnym cyklem życia i helper jest typową usługą, wydaje się mieszanie dwóch obiektów o bardzo różnym zakresie/cyklu życia.

Zazwyczaj encja domeny ma swój własny cykl życia od momentu utworzenia, trwałość do jego GC. Z drugiej strony, pomocnik lub usługa jest statyczna lub lepsza, z cyklem życia równym całej aplikacji, np. fasola sprężysta.

Gdy jednostka domeny zawiera odniesienie do usługi, może spowodować poważne problemy. Na przykład. każde wywołanie repozytorium Get wymaga wstrzyknięcia referencji tej usługi do encji domeny. Zalecam, aby unikać tego wzorca.

Dla mnie nie jest oczywiste, kto wykona instancję Helper.

4

Oto niektóre zastosowania klas wewnętrznych.

  • Klasy wewnętrzne służą do uzyskiwania funkcjonalności, którą można uzyskać jako obiekt lepiej niż metoda.
  • Można z nich korzystać w przypadku, gdy wymagany jest zestaw wielu operacji, a szanse ponownego użycia są dobre w klasie i nie mają zastosowania poza klasą.
  • Klasy wewnętrzne są również tworzone w celu osiągnięcia wielu dziedziczenia.
  • Klasy wewnętrzne są używane, gdy są przydatne w kontekście zajęć.
  • Służą do oddzielania logiki wewnątrz klasy.

Tak więc, jeśli masz jakieś wymaganie, możesz użyć pasujących punktów powyżej niż klasa wewnętrzna. Zawsze lepiej jest stworzyć wewnętrzną klasę private, aby uniemożliwić dostęp innym klasom. W twoim przypadku użycie klasy wewnętrznej jest pomocne w tworzeniu czytelnej kodu i oddzielnej logice w klasie.

0

Hild, tak, w wielu przypadkach warto używać wewnętrznej klasy.

Pomyśl o tym w ten sposób - klasa wewnętrzna będzie żyła i umiera z klasą zewnętrzną, więc każda funkcjonalność, która jest specjalnie potrzebna dla klasy zewnętrznej, może zostać dodana do klasy wewnętrznej. Popularnymi przykładami są - w większości przypadków nasłuchiwania - typy KeyListeners, MouseListeners, eventListeners.

Klasy w języku Java umożliwiają korzystanie z określonej funkcjonalności, ale czasami może być wymagana osobna wyspecjalizowana funkcja, ale musi być również ściśle powiązana z klasą, którą projektujesz.

Istnieją cztery typy klas wewnętrznych. Proste wyszukiwanie google pomoże ci dowiedzieć się więcej na ich temat.

0

Istnieją dwa dodatkowe typy klas wewnętrznych. Możesz zadeklarować wewnętrzną klasę w ciele metody. Te klasy są znane jako klasy lokalne. Możesz również zadeklarować wewnętrzną klasę w ciele metody bez nazywania klasy. Te klasy są znane jako anonimowe klasy.

Klasa lokalna: użyj go, jeśli chcesz utworzyć więcej niż jedną instancję klasy, uzyskać dostęp do jej konstruktora lub wprowadzić nowy, nazwany typ (ponieważ na przykład musisz wywołać dodatkowe metody później).

Klasa anonimowa: użyj jej, jeśli chcesz zadeklarować pola lub dodatkowe metody.

0

Kiedy korzystać z zajęć wewnętrznych?

  1. klasa wewnętrzna nie potrzebuje żadnego dodatkowego lub oddzielny plik, aby umieścić.
  2. Klasy wewnętrzne są stosunkowo małe i ściśle powiązane z klasą "rodzica" lub "klasą zewnętrzną". Unika wielu klas pomocniczych i pasuje do wyjaśnienia zasady OOD powstrzymywania.
  3. Cały kod w tym samym pliku zwiększa czytelność i zwiększa wydajność (np. Kod online). Ich znaczenie rośnie w kodowaniu i traktowane jako dobra praktyka.
  4. Anonimowe klasy wewnętrzne są bardzo przydatne, gdy chcesz zdefiniować wywołania zwrotne w locie.
  5. Obiekt klasy wewnętrznej może uzyskać dostęp do implementacji obiektu , który go utworzył - WŁĄCZAJĄC prywatne dane.
6

z Java SE Docs

Dlaczego Użyj zagnieżdżone klasy?

To sposób logicznie grupowanie klas, które są używane tylko w jednym miejscu: Jeśli klasa jest przydatny tylko do jednej drugiej klasy, to logiczne jest, aby osadzić go w tej klasie i trzymać je razem. Zagnieżdżanie takich "klas pomocniczych" sprawia, że ​​ich pakiet jest bardziej uproszczony.

Zwiększa enkapsulacji: Rozważmy dwie klasy najwyższego poziomu A i B, gdzie B potrzebuje dostępu do członków, które w przeciwnym razie zostałyby uznane za prywatne. Ukrywając klasę B w klasie A, członkowie A mogą zostać zadeklarowani jako prywatni, a B może uzyskać do nich dostęp. Ponadto samo B może być ukryte przed światem zewnętrznym.

Tak Tak, warto użyć FooHelper jako wewnętrznej klasy.

Powiązane problemy