Jaka jest główna różnica między klasą wewnętrzną a statyczną klasą zagnieżdżoną w Javie? Czy projekt / wdrożenie odgrywa rolę w wyborze jednego z nich?
java
inner-classes
static-classes
Wszechmocny
źródło
źródło
item 22 : Favor static member classes over non static
Odpowiedzi:
Z samouczka Java :
Dostęp do klas zagnieżdżonych statycznie można uzyskać za pomocą otaczającej nazwy klasy:
Na przykład, aby utworzyć obiekt dla statycznej klasy zagnieżdżonej, użyj następującej składni:
Obiekty będące instancjami klasy wewnętrznej istnieją w instancji klasy zewnętrznej. Rozważ następujące klasy:
Instancja InnerClass może istnieć tylko w ramach instancji OuterClass i ma bezpośredni dostęp do metod i pól swojej instancji.
Aby utworzyć instancję klasy wewnętrznej, musisz najpierw utworzyć instancję klasy zewnętrznej. Następnie utwórz wewnętrzny obiekt w obrębie zewnętrznego obiektu za pomocą następującej składni:
patrz: Tutorial Java - zagnieżdżone klasy
Dla kompletności należy zauważyć, że istnieje również coś takiego jak klasa wewnętrzna bez otaczającej instancji :
Tutaj
new A() { ... }
jest klasą wewnętrzną zdefiniowaną w kontekście statycznym i nie ma otaczającej instancji.źródło
import OuterClass.StaticNestedClass;
następnie odwołaj się do klasy tak jak OuterClass.OuterClass.InnerClass innerObject = outerObject.new InnerClass();
?Samouczek Java mówi :
W języku potocznym terminy „zagnieżdżone” i „wewnętrzne” są używane zamiennie przez większość programistów, ale użyję poprawnego terminu „klasa zagnieżdżona”, która obejmuje zarówno wewnętrzne, jak i statyczne.
Klasy mogą być zagnieżdżane w nieskończoność , np. Klasa A może zawierać klasę B, która zawiera klasę C, która zawiera klasę D itp. Jednak więcej niż jeden poziom zagnieżdżania klas jest rzadki, ponieważ jest to ogólnie zły projekt.
Istnieją trzy powody, dla których możesz utworzyć zagnieżdżoną klasę:
Istnieją cztery rodzaje zagnieżdżonych klas w Javie . W skrócie są to:
Pozwól mi rozwinąć bardziej szczegółowo.
Klasy statyczne
Klasy statyczne są najłatwiejsze do zrozumienia, ponieważ nie mają nic wspólnego z instancjami zawierającej klasy.
Klasa statyczna to klasa zadeklarowana jako element statyczny innej klasy. Podobnie jak inne elementy statyczne, taka klasa jest tak naprawdę tylko wieszakiem, który używa zawierającej klasy jako przestrzeni nazw, np . Klasa Koza zadeklarowana jako element statyczny klasy Rhino w pakiecie pizza jest znana pod nazwą pizza.Rhino.Goat .
Szczerze mówiąc, klasy statyczne są dość bezwartościową funkcją, ponieważ klasy są już podzielone na przestrzenie nazw według pakietów. Jedynym realnym możliwym powodem do stworzenia klasy statycznej jest to, że taka klasa ma dostęp do prywatnych elementów statycznych zawierającej klasę, ale uważam, że jest to dość kiepskie uzasadnienie istnienia funkcji klasy statycznej.
Klasy wewnętrzne
Klasa wewnętrzna to klasa zadeklarowana jako element niestatyczny innej klasy:
Podobnie jak w przypadku klasy statycznej, klasa wewnętrzna jest znana jako kwalifikowana na podstawie nazwy klasy zawierającej, pizza.Rhino.Goat , ale wewnątrz klasy zawierającej może być znana pod nazwą prostą. Jednak każde wystąpienie klasy wewnętrznej jest powiązane z konkretnym wystąpieniem klasy zawierającej: powyżej, Koza stworzona w jerry , jest domyślnie powiązana z instancją Rhino w tej jerry . W przeciwnym razie jawne skojarzenie instancji Rhino jest jawne, gdy tworzymy instancję Koza :
(Zauważ, że określasz wewnętrzny typ jako „ Koza” w dziwnej nowej składni: Java wyprowadza typ zawierający z części nosorożca . I tak, nowa rhino.Goat () też miałby dla mnie większy sens).
Co nas to zyskuje? Cóż, instancja klasy wewnętrznej ma dostęp do elementów instancji zawierającej instancję klasy. O tych członkach obejmujących instancję odwołuje się wewnątrz klasy wewnętrznej tylko poprzez ich proste nazwy, a nie przez to ( to w klasie wewnętrznej odnosi się do instancji klasy wewnętrznej, a nie powiązanej zawierającej instancji klasy):
W wewnętrznej klasy, można odwołać się do tego od zawierającego klasy jako Rhino.this , i można użyć tego , aby odnieść się do swoich członków, np Rhino.this.barry .
Lokalne klasy wewnętrzne
Lokalna klasa wewnętrzna to klasa zadeklarowana w treści metody. Taka klasa jest znana tylko w ramach jej metody zawierającej, więc można ją tworzyć tylko i tworzyć do niej elementy. Korzyścią jest to, że lokalna instancja klasy wewnętrznej jest powiązana i może uzyskiwać dostęp do końcowych zmiennych lokalnych swojej metody zawierającej. Gdy instancja korzysta z ostatecznego ustawienia lokalnego swojej metody zawierającej, zmienna zachowuje wartość, którą trzymała w momencie jej tworzenia, nawet jeśli zmienna wykroczyła poza zakres (jest to w rzeczywistości surowa, ograniczona wersja zamknięć Javy).
Ponieważ lokalna klasa wewnętrzna nie jest członkiem klasy ani pakietu, nie jest zadeklarowana z poziomem dostępu. (Wyjaśnij jednak, że jego członkowie mają poziomy dostępu jak w normalnej klasie).
Jeśli lokalna klasa wewnętrzna jest zadeklarowana w metodzie instancji, tworzenie instancji klasy wewnętrznej jest powiązane z instancją utrzymywaną przez metodę zawierającą to w momencie tworzenia instancji, a zatem elementy instancji klasy zawierającej są dostępne tak jak w instancji klasa wewnętrzna. Lokalna klasa wewnętrzna jest tworzona po prostu poprzez jej nazwę, np. Lokalna klasa wewnętrzna Cat jest tworzona jako nowa Cat () , a nie nowa this.Cat (), jak można się spodziewać.
Anonimowe klasy wewnętrzne
Anonimowa klasa wewnętrzna to wygodny pod względem składni sposób pisania lokalnej klasy wewnętrznej. Najczęściej lokalna klasa wewnętrzna jest tworzona najwyżej tylko raz za każdym razem, gdy uruchamiana jest jej metoda zawierająca. Byłoby więc miło, gdybyśmy mogli połączyć definicję lokalnej klasy wewnętrznej i jej pojedynczą instancję w jedną wygodną formę składni, a także byłoby miło, gdybyśmy nie musieli wymyślać nazwy klasy (im mniej pomocna imiona zawierają Twój kod, tym lepiej). Anonimowa klasa wewnętrzna pozwala na obie te rzeczy:
Jest to wyrażenie zwracające nowe wystąpienie nienazwanej klasy, które rozszerza ParentClassName . Nie możesz dostarczyć własnego konstruktora; dostarczany jest domyślnie jeden, który po prostu wywołuje superkonstruktor, więc podane argumenty muszą pasować do superkonstruktora. (Jeśli rodzic zawiera wiele konstruktorów, ten „najprostszy” nazywa się „najprostszym”, co wynika z dość złożonego zestawu zasad, których nie warto zawracać głowy szczegółową nauką - wystarczy zwrócić uwagę na to, co mówią NetBeans lub Eclipse.)
Alternatywnie możesz określić interfejs do wdrożenia:
Taka deklaracja tworzy nową instancję nienazwanej klasy, która rozszerza Object i implementuje InterfaceName . Ponownie nie możesz dostarczyć własnego konstruktora; w tym przypadku Java domyślnie dostarcza konstruktora no-arg, nic nie rób (więc w tym przypadku nigdy nie będzie argumentów konstruktora).
Chociaż nie możesz nadać anonimowemu konstruktorowi klasy wewnętrznej, nadal możesz wykonać dowolną konfigurację, używając bloku inicjalizującego (blok {} umieszczony poza jakąkolwiek metodą).
Wyjaśnij, że anonimowa klasa wewnętrzna jest po prostu mniej elastycznym sposobem tworzenia lokalnej klasy wewnętrznej za pomocą jednej instancji. Jeśli chcesz lokalną klasę wewnętrzną, która implementuje wiele interfejsów lub która implementuje interfejsy, jednocześnie rozszerzając klasę inną niż Object lub która określa własnego konstruktora, utkniesz tworząc regularną lokalną klasę wewnętrzną.
źródło
Nie sądzę, aby prawdziwa różnica stała się jasna w powyższych odpowiedziach.
Najpierw popraw warunki:
Jak dotąd odpowiedź Martina jest słuszna. Jednak faktyczne pytanie brzmi: jaki jest cel deklarowania statycznej klasy zagnieżdżonej, czy nie?
Używasz statycznych klas zagnieżdżonych, jeśli chcesz utrzymać klasy razem, jeśli należą one do siebie lokalnie lub jeśli klasa zagnieżdżona jest używana wyłącznie w klasie zamykającej. Nie ma semantycznej różnicy między statyczną klasą zagnieżdżoną a każdą inną klasą.
Niestatyczne klasy zagnieżdżone to inna bestia. Podobne do anonimowych klas wewnętrznych, takie zagnieżdżone klasy są w rzeczywistości zamknięciami. Oznacza to, że przechwytują otaczający ich zakres i otaczającą go instancję i udostępniają ją. Być może jakiś przykład to wyjaśni. Zobacz ten skrót kontenera:
W takim przypadku chcesz mieć odniesienie z elementu podrzędnego do kontenera nadrzędnego. Korzystanie z niestatycznej klasy zagnieżdżonej działa bezproblemowo. Możesz uzyskać dostęp do zamykającej instancji kontenera za pomocą składni
Container.this
.Bardziej ostre wyjaśnienia:
Jeśli spojrzysz na bajtowe kody Java, kompilator generuje (niestatyczną) klasę zagnieżdżoną, może stać się jeszcze jaśniejszy:
Jak widać, kompilator tworzy ukryte pole
Container this$0
. Jest to ustawiane w konstruktorze, który ma dodatkowy parametr typu Kontener, aby określić dołączającą instancję. Nie możesz zobaczyć tego parametru w źródle, ale kompilator domyślnie generuje go dla zagnieżdżonej klasy.Przykład Martina
byłby więc skompilowany do wywołania czegoś podobnego (w kodach bajtowych)
Ze względu na kompletność:
Anonimowa klasa jest doskonałym przykładem niestatycznej zagnieżdżonej klasy, która po prostu nie ma z nią żadnej nazwy i nie można do niej odwoływać się później.
źródło
Myślę, że żadna z powyższych odpowiedzi nie wyjaśnia prawdziwej różnicy między klasą zagnieżdżoną a statyczną klasą zagnieżdżoną pod względem projektowania aplikacji:
Przegląd
Zagnieżdżona klasa może być niestatyczna lub statyczna iw każdym przypadku jest klasą zdefiniowaną w innej klasie . Klasa zagnieżdżona powinna istnieć tylko po to, aby służyć była klasą zamykającą , jeśli klasa zagnieżdżona jest przydatna dla innych klas (nie tylko obejmującej), powinna zostać zadeklarowana jako klasa najwyższego poziomu.
Różnica
Niestatyczna klasa zagnieżdżona : jest domyślnie powiązana z otaczającą instancją klasy zawierającej, co oznacza, że możliwe jest wywoływanie metod i zmiennych dostępu do zamykającej instancji. Jednym z powszechnych zastosowań niestatycznej klasy zagnieżdżonej jest zdefiniowanie klasy adaptera.
Statyczna klasa zagnieżdżona : nie może uzyskać dostępu do instancji klasy otaczającej i wywołać na niej metody, dlatego należy jej użyć, gdy klasa zagnieżdżona nie wymaga dostępu do instancji klasy zamykającej. Częstym zastosowaniem statycznej klasy zagnieżdżonej jest implementacja komponentów obiektu zewnętrznego.
Wniosek
Główną różnicą między nimi z punktu widzenia projektu jest: niestatyczna klasa zagnieżdżona może uzyskać dostęp do wystąpienia klasy kontenera, podczas gdy statyczna nie .
źródło
Mówiąc prościej, potrzebujemy klas zagnieżdżonych przede wszystkim dlatego, że Java nie zapewnia zamknięć.
Klasy zagnieżdżone to klasy zdefiniowane w treści innej klasy zamykającej. Są dwojakiego rodzaju - statyczne i niestatyczne.
Są one traktowane jako członkowie klasy zamykającej, dlatego można określić dowolny z czterech specyfikatorów dostępu -
private, package, protected, public
. Nie mamy tego luksusu z klasami na najwyższym poziomie, które mogą być zadeklarowanepublic
lub prywatne.Klasy wewnętrzne zwane także klasami bez stosu mają dostęp do innych członków najwyższej klasy, nawet jeśli są zadeklarowane jako prywatne, podczas gdy statyczne klasy zagnieżdżone nie mają dostępu do innych członków najwyższej klasy.
Inner1
jest naszą statyczną klasą wewnętrzną iInner2
jest naszą klasą wewnętrzną, która nie jest statyczna. Kluczową różnicą między nimi jest to, że nie można utworzyćInner2
instancji bez Outera, ponieważ można utworzyćInner1
obiekt niezależnie.Kiedy używałbyś klasy wewnętrznej?
Pomyśl o sytuacji, w której
Class A
iClass B
są powiązane,Class B
muszą uzyskać dostęp doClass A
członków iClass B
są powiązane tylko zClass A
. Klasy wewnętrzne pojawiają się na zdjęciu.Aby utworzyć instancję klasy wewnętrznej, musisz utworzyć instancję klasy zewnętrznej.
lub
Kiedy użyjesz statycznej klasy wewnętrznej?
Zdefiniowałbyś statyczną klasę wewnętrzną, gdy wiesz, że nie ma ona żadnego związku z wystąpieniem otaczającej klasy / najwyższej klasy. Jeśli twoja klasa wewnętrzna nie używa metod ani pól klasy zewnętrznej, to tylko marnowanie miejsca, więc zrób to statycznie.
Na przykład, aby utworzyć obiekt dla statycznej klasy zagnieżdżonej, użyj następującej składni:
Zaletą statycznej klasy zagnieżdżonej jest to, że nie potrzebuje do działania obiektu zawierającego klasę / najwyższą klasę. Może to pomóc w zmniejszeniu liczby obiektów tworzonych przez aplikację w czasie wykonywania.
źródło
OuterClass.Inner2 inner = outer.new Inner2();
?static inner
jest sprzecznością pod względem.Oto kluczowe różnice i podobieństwa między wewnętrzną klasą Java a statyczną klasą zagnieżdżoną.
Mam nadzieję, że to pomoże!
Klasa wewnętrzna
Powiązany z instancją klasy otaczającej, więc aby utworzyć jej instancję, najpierw potrzebna jest instancja klasy zewnętrznej (zwróć uwagę na nowe słowo kluczowe miejsce):
Nie można określić wszelkie elementy statyczne sama
Statycznie zagnieżdżona klasa
Nie można uzyskać dostępu do metod lub pól instancji klasy zewnętrznej
Nie jest powiązany z żadnym wystąpieniem obejmującym klasę. Aby go utworzyć:
Podobieństwa
Dlaczego warto korzystać z klas zagnieżdżonych?
Według dokumentacji Oracle istnieje kilka powodów ( pełna dokumentacja ):
źródło
Myślę, że konwencja, która jest ogólnie przestrzegana, jest następująca:
Jednak kilka innych punktów do zapamiętania to:
Klasy najwyższego poziomu i statyczna klasa zagnieżdżona są semantycznie takie same, z tym wyjątkiem, że w przypadku statycznej klasy zagnieżdżonej może ona odwoływać się statycznie do prywatnych pól statycznych / metod swojej zewnętrznej klasy [macierzystej] i odwrotnie.
Klasy wewnętrzne mają dostęp do zmiennych instancji obejmującej instancję klasy zewnętrznej [nadrzędnej]. Jednak nie wszystkie klasy wewnętrzne mają instancje zamykające, na przykład klasy wewnętrzne w kontekstach statycznych, takie jak klasa anonimowa używana w statycznym bloku inicjującym, nie mają takiej możliwości.
Klasa anonimowa domyślnie rozszerza klasę nadrzędną lub implementuje interfejs nadrzędny i nie ma dalszej klauzuli, aby rozszerzyć inną klasę lub zaimplementować więcej interfejsów. Więc,
new YourClass(){};
znaczyclass [Anonymous] extends YourClass {}
new YourInterface(){};
znaczyclass [Anonymous] implements YourInterface {}
Czuję, że tym większym pytaniem pozostaje otwarte, które z nich użyć i kiedy? Cóż, to głównie zależy od tego, z jakim scenariuszem masz do czynienia, ale przeczytanie odpowiedzi udzielonej przez @jrudolph może pomóc ci podjąć decyzję.
źródło
Klasa zagnieżdżona: klasa wewnątrz klasy
Rodzaje:
Różnica:
Niestatyczna klasa zagnieżdżona [klasa wewnętrzna]
W niestatycznej klasie zagnieżdżonej obiekt klasy wewnętrznej istnieje w obiekcie klasy zewnętrznej. Tak więc element danych klasy zewnętrznej jest dostępny dla klasy wewnętrznej. Aby więc stworzyć obiekt klasy wewnętrznej, musimy najpierw stworzyć obiekt klasy zewnętrznej.
Statycznie zagnieżdżona klasa
W statycznej klasie zagnieżdżonej obiekt klasy wewnętrznej nie potrzebuje obiektu klasy zewnętrznej, ponieważ słowo „statyczny” oznacza brak potrzeby tworzenia obiektu.
Jeśli chcesz uzyskać dostęp do x, napisz następującą metodę wewnętrzną
źródło
Instancja klasy wewnętrznej jest tworzona, gdy tworzona jest instancja klasy zewnętrznej. Dlatego członkowie i metody klasy wewnętrznej mają dostęp do elementów i metod instancji (obiektu) klasy zewnętrznej. Kiedy instancja klasy zewnętrznej wykracza poza zakres, również instancje klasy wewnętrznej przestają istnieć.
Statyczna klasa zagnieżdżona nie ma konkretnej instancji. Jest po prostu ładowany, gdy jest używany po raz pierwszy (podobnie jak metody statyczne). Jest to całkowicie niezależna jednostka, której metody i zmienne nie mają żadnego dostępu do instancji klasy zewnętrznej.
Statyczne zagnieżdżone klasy nie są sprzężone z obiektem zewnętrznym, są szybsze i nie zajmują pamięci sterty / stosu, ponieważ nie jest konieczne tworzenie instancji takiej klasy. Dlatego podstawową zasadą jest próba zdefiniowania statycznej zagnieżdżonej klasy o możliwie ograniczonym zakresie (prywatny> = klasa> = chroniony> = publiczny), a następnie konwersja do klasy wewnętrznej (poprzez usunięcie „statycznego” identyfikatora) i poluzowanie zakres, jeśli jest to naprawdę konieczne.
źródło
Istnieje subtelność dotycząca użycia zagnieżdżonych klas statycznych, które mogą być przydatne w niektórych sytuacjach.
Podczas gdy atrybuty statyczne są tworzone, zanim klasa zostanie utworzona za pomocą swojego konstruktora, atrybuty statyczne w zagnieżdżonych klasach statycznych nie wydają się być tworzone, dopóki nie zostanie wywołany konstruktor klasy, a przynajmniej nie po pierwszym odwołaniu do atrybutów, nawet jeśli są oznaczone jako „ostateczne”.
Rozważ ten przykład:
Mimo że zarówno „zagnieżdżone”, jak i „wewnętrznaItem” są zadeklarowane jako „statyczne końcowe”. ustawienie nested.innerItem ma miejsce dopiero po utworzeniu instancji klasy (a przynajmniej dopiero po pierwszym odwołaniu do zagnieżdżonego elementu statycznego), jak można to zobaczyć, komentując i usuwając komentarz z wierszy, do których się odwołuję, powyżej. To samo nie dotyczy prawdy „outerItem”.
Przynajmniej to widzę w Javie 6.0.
źródło
Terminy są używane zamiennie. Jeśli chcesz być naprawdę pedantyczny o nim, to mógłby zdefiniować „zagnieżdżone klasy” odnosi się do statycznego klasy wewnętrznej, która nie ma jednej instancji otaczającą. W kodzie możesz mieć coś takiego:
To nie jest tak naprawdę powszechnie przyjęta definicja.
źródło
W przypadku tworzenia instancji instancja niestatycznej klasy wewnętrznej jest tworzona za pomocą odwołania do obiektu klasy zewnętrznej, w którym jest zdefiniowana. Oznacza to, że zawiera instancję. Ale instancja statycznej klasy wewnętrznej jest tworzona z referencją klasy zewnętrznej, a nie z referencją obiektu klasy zewnętrznej. Oznacza to, że nie zawiera on instancji.
Na przykład:
źródło
Nie sądzę, aby można było tu wiele dodać, większość odpowiedzi doskonale wyjaśnia różnice między statyczną klasą zagnieżdżoną a klasami wewnętrznymi. Należy jednak wziąć pod uwagę następujący problem podczas korzystania z klas zagnieżdżonych a klas wewnętrznych. Jak wspomina w kilku odpowiedziach Klasy wewnętrzne nie może być instancja bez i wystąpienie ich załączając klasy co oznacza, że HOLD jest wskaźnik do instancji swojej klasie otaczającą, która może prowadzić do przepełnienia pamięci lub wyjątek przepełnienie stosu ze względu na fakt, GC nie będzie w stanie wyrzucić śmieci do otaczających klas, nawet jeśli nie będą już używane. Aby to wyjaśnić, sprawdź następujący kod:
Jeśli usuniesz komentarz na temat
// inner = null;
: Program wyda komunikat „ Jestem zniszczony! ”, Ale zachowanie tego komentarza nie spowoduje.Powodem jest to, że biała wewnętrzna instancja jest nadal wywoływana, GC nie może jej zebrać, a ponieważ odwołuje się (ma wskaźnik) do zewnętrznej instancji, nie jest również gromadzona. Mając wystarczającą liczbę tych obiektów w projekcie i może zabraknąć pamięci.
W porównaniu ze statycznymi klasami wewnętrznymi, które nie utrzymują punktu do instancji klasy wewnętrznej, ponieważ nie jest ona związana z instancją, ale jest związana z klasą. Powyższy program może wypisać komunikat „ Jestem zniszczony! ”, Jeśli uczynisz klasę wewnętrzną statyczną i utworzoną przy pomocy instancji
Outer.Inner i = new Outer.Inner();
źródło
Klasa zagnieżdżona jest bardzo ogólnym terminem: każda klasa, która nie jest najwyższym poziomem, jest klasą zagnieżdżoną. Klasa wewnętrzna to niestatyczna klasa zagnieżdżona. Joseph Darcy napisał bardzo ładne wyjaśnienie na temat klas zagnieżdżonych, wewnętrznych, członkowskich i klas najwyższego poziomu .
źródło
Ummm ... klasa wewnętrzna JEST klasą zagnieżdżoną ... masz na myśli klasę anonimową i klasę wewnętrzną?
Edycja: Jeśli faktycznie miałeś na myśli wewnętrzną vs anonimową ... klasa wewnętrzna to po prostu klasa zdefiniowana w klasie, takiej jak:
Podczas gdy klasa anonimowa jest rozszerzeniem klasy zdefiniowanej anonimowo, więc nie zdefiniowano żadnej rzeczywistej klasy, jak w:
Dalsza edycja:
Wikipedia twierdzi, że jest różnica w Javie, ale pracuję z Javą od 8 lat i po raz pierwszy usłyszałem takie rozróżnienie ... nie wspominając o tym, że nie ma tam żadnych referencji na poparcie roszczenia ... na dole linia, klasa wewnętrzna to klasa zdefiniowana w klasie (statyczna lub nie), a zagnieżdżona jest tylko innym terminem oznaczającym to samo.
Istnieje subtelna różnica między statyczną i niestatyczną klasą zagnieżdżoną ... w zasadzie nie-statyczne klasy wewnętrzne mają niejawny dostęp do pól instancji i metod klasy otaczającej (dlatego nie można ich budować w kontekście statycznym, będzie to kompilator błąd). Z drugiej strony statyczne klasy zagnieżdżone nie mają niejawnego dostępu do pól i metod instancji i mogą być konstruowane w kontekście statycznym.
źródło
Kierowanie na ucznia, który jest nowicjuszem w Javie i / lub zagnieżdżonych klasach
Klasy zagnieżdżone mogą być:
1. Statyczne klasy zagnieżdżone.
2. Niestatyczne klasy zagnieżdżone. (znany również jako klasy wewnętrzne ) => Pamiętaj o tym
1. Klasy wewnętrzne
Przykład:
Klasy wewnętrzne to podzbiory klas zagnieżdżonych:
Specjalność klasy wewnętrznej:
2.Statyczne zagnieżdżone klasy:
przykład:
Przypadek 1: Tworzenie instancji statycznej klasy zagnieżdżonej z klasy nieobjętej klauzulą
Przypadek 2: Tworzenie instancji statycznej klasy zagnieżdżonej z klasy zamykającej
Specjalność klas statycznych:
Wniosek:
Pytanie: Jaka jest główna różnica między klasą wewnętrzną a statyczną klasą zagnieżdżoną w Javie?
Odpowiedź: wystarczy przejrzeć specyfikę każdej klasy wspomnianej powyżej.
źródło
Zarówno klasa wewnętrzna, jak i zagnieżdżona klasa statyczna w Javie są klasami zadeklarowanymi w innej klasie, znanej jako klasa najwyższego poziomu w Javie. W terminologii Java, jeśli zadeklarujesz klasę zagnieżdżoną jako statyczną, będzie ona nazywana klasą zagnieżdżoną w Javie, podczas gdy niestatyczna klasa zagnieżdżona będzie po prostu nazywana klasą wewnętrzną.
Co to jest klasa wewnętrzna w Javie?
Każda klasa, która nie jest najwyższego poziomu lub nie została zadeklarowana w innej klasie, jest znana jako klasa zagnieżdżona, a spośród tych klas zagnieżdżonych, które są zadeklarowane jako niestatyczne, są znane jako klasa wewnętrzna w Javie. istnieją trzy rodzaje klasy wewnętrznej w Javie:
1) Lokalna klasa wewnętrzna - deklarowana w bloku kodu lub metodzie.
2) Anonimowa klasa wewnętrzna - to klasa, która nie ma nazwy, do której można się odwoływać i jest inicjowana w tym samym miejscu, w którym została utworzona.
3) Członek klasy wewnętrznej - deklarowany jako niestatyczny element klasy zewnętrznej.
Co to jest zagnieżdżona klasa statyczna w Javie?
Zagnieżdżona klasa statyczna to kolejna klasa zadeklarowana w klasie jako element członkowski i uczyniona statyczną. Zagnieżdżona klasa statyczna jest również zadeklarowana jako członek klasy zewnętrznej i może być prywatna, publiczna lub chroniona jak każdy inny element. Jedną z głównych zalet zagnieżdżonej klasy statycznej w porównaniu z klasą wewnętrzną jest to, że instancja zagnieżdżonej klasy statycznej nie jest dołączona do żadnej otaczającej instancji klasy zewnętrznej. Nie potrzebujesz również żadnego wystąpienia klasy zewnętrznej, aby utworzyć wystąpienie zagnieżdżonej klasy statycznej w Javie .
1) Może uzyskać dostęp do danych statycznych należących do klasy zewnętrznej, w tym prywatnych.
2) Statycznie zagnieżdżona klasa nie może uzyskać dostępu do elementu lub metody niestatycznej (instancji) .
Ref: Klasa wewnętrzna i zagnieżdżona klasa statyczna w Javie z przykładem
źródło
Myślę, że ludzie tutaj powinni zauważyć, że: Statyczna klasa gniazd to tylko pierwsza klasa wewnętrzna. Na przykład:
Podsumowując, klasa statyczna nie zależy od tego, która klasa zawiera. Nie mogą więc w normalnej klasie. (ponieważ normalna klasa potrzebuje instancji).
źródło
Kiedy deklarujemy statyczną klasę członka w klasie, jest ona znana jako klasa zagnieżdżona najwyższego poziomu lub statyczna klasa zagnieżdżona. Można to wykazać jak poniżej:
Kiedy deklarujemy niestatyczną klasę członka w klasie, jest to znane jako klasa wewnętrzna. Klasa wewnętrzna może być pokazana jak poniżej:
źródło
Oto przykład
static nested class
iinner class
:OuterClass.java
OuterClassTest:
źródło
Myślę, że żadna z powyższych odpowiedzi nie daje prawdziwego przykładu różnicy między klasą zagnieżdżoną a statyczną klasą zagnieżdżoną pod względem projektowania aplikacji. Główną różnicą między statyczną klasą zagnieżdżoną a klasą wewnętrzną jest możliwość dostępu do zewnętrznego pola instancji klasy.
Rzućmy okiem na dwa następujące przykłady.
Statyczna klasa zagnieżdżenia: Dobrym przykładem użycia statycznych zagnieżdżonych klas jest wzorzec konstruktora ( https://dzone.com/articles/design-patterns-the-builder-pattern ).
W przypadku BankAccount używamy statycznej zagnieżdżonej klasy, głównie dlatego, że
Przed klasą zewnętrzną można utworzyć statyczną instancję klasy gniazda.
We wzorcu konstruktora konstruktor jest klasą pomocniczą, która służy do tworzenia konta bankowego.
Klasa wewnętrzna: powszechnym zastosowaniem klas wewnętrznych jest definiowanie modułu obsługi zdarzeń. https://docs.oracle.com/javase/tutorial/uiswing/events/generalrules.html
W przypadku MyClass używamy klasy wewnętrznej, głównie dlatego, że:
Klasa wewnętrzna MyAdapter musi uzyskać dostęp do elementu klasy zewnętrznej.
W tym przykładzie MyAdapter jest powiązany tylko z MyClass. Żadne inne klasy nie są powiązane z MyAdapter. więc lepiej zorganizować je razem bez użycia konwencji nazw
źródło
Schemat
Główną różnicą pomiędzy
static nested
inon-static nested
klas jest to, żestatic nested
nie ma dostępu do non-statycznych członków klasy zewnętrznyźródło
Przede wszystkim nie ma takiej klasy zwanej klasą statyczną. Używanie modyfikatora statycznego z klasą wewnętrzną (zwaną klasą zagnieżdżoną) mówi, że jest to element statyczny klasy zewnętrznej, co oznacza, że możemy uzyskać do niej dostęp tak jak w przypadku innych elementów statycznych i nie posiadając żadnych wystąpienie klasy zewnętrznej. (Co jest początkowo zaletą statyczną.)
Różnica między używaniem klasy zagnieżdżonej a zwykłą klasą wewnętrzną jest następująca:
Najpierw możemy utworzyć instancję klasy zewnętrznej, a następnie możemy uzyskać dostęp do wewnętrznej.
Ale jeśli zagnieżdżona jest klasa, wówczas składnia jest następująca:
Który używa składni statycznej jako normalnej implementacji słowa kluczowego static.
źródło
Język programowania Java pozwala zdefiniować klasę w innej klasie. Taka klasa nazywa się klasą zagnieżdżoną i jest zilustrowana tutaj:
Klasy zagnieżdżone są podzielone na dwie kategorie: statyczne i niestatyczne. Klasy zagnieżdżone, które są zadeklarowane jako statyczne, nazywane są statycznymi klasami zagnieżdżonymi. Niestatyczne klasy zagnieżdżone nazywane są klasami wewnętrznymi. Jedną z rzeczy, o których powinniśmy pamiętać, jest to, że statyczne klasy zagnieżdżone (klasy wewnętrzne) mają dostęp do innych członków klasy zamykającej, nawet jeśli są one uznane za prywatne. Statycznie zagnieżdżone klasy mają dostęp do innych członków klasy zamykającej tylko wtedy, gdy są statyczne. Nie ma dostępu do niestatycznych członków klasy zewnętrznej. Podobnie jak w przypadku metod i zmiennych klas, statycznie zagnieżdżona klasa jest powiązana z jej klasą zewnętrzną. Na przykład, aby utworzyć obiekt dla statycznej klasy zagnieżdżonej, użyj następującej składni:
Aby utworzyć instancję klasy wewnętrznej, musisz najpierw utworzyć instancję klasy zewnętrznej. Następnie utwórz wewnętrzny obiekt w obrębie zewnętrznego obiektu za pomocą następującej składni:
Dlaczego używamy zagnieżdżonych klas
Źródło: The Java ™ Tutorials - Nested Classes
źródło
Różnica polega na tym, że deklaracja klasy zagnieżdżonej, która jest również statyczna, może być utworzona instancji poza klasą otaczającą.
Jeśli masz zagnieżdżoną deklarację klasy, która nie jest statyczna, zwana także klasą wewnętrzną , Java nie pozwoli na utworzenie jej, chyba że za pośrednictwem klasy otaczającej. Obiekt utworzony z klasy wewnętrznej jest powiązany z obiektem utworzonym z klasy zewnętrznej, więc klasa wewnętrzna może odwoływać się do pól zewnętrznej.
Ale jeśli jest statyczny, to łącze nie istnieje, nie można uzyskać dostępu do zewnętrznych pól (z wyjątkiem zwykłego odwołania, jak każdy inny obiekt), a zatem można utworzyć instancję samej klasy zagnieżdżonej.
źródło
Jest dość prosty, porównując statyczne klasy lokalne i niestatyczne klasy wewnętrzne
Różnice:
Statyczna klasa lokalna:
Może uzyskać dostęp tylko do statycznych członków klasy zewnętrznej.
Nie można mieć statycznych inicjatorów
Nie można uzyskać dostępu bezpośrednio spoza funkcji, w której jest zadeklarowana
źródło
Zilustrowałem różne możliwe scenariusze poprawek i błędów, które mogą wystąpić w kodzie Java.
źródło