Nestede klasser i Java

1. Introduksjon

Denne opplæringen er en rask og nøyaktig introduksjon til nestede klasser på Java-språket.

Enkelt sagt, Java lar oss definere klasser i andre klasser. Nestede klasser gjør det mulig for oss å logisk gruppere klasser som bare brukes på ett sted, skrive mer lesbar og vedlikeholdbar kode og øke innkapslingen.

Før vi begynner, la oss ta en titt på flere typer nestede klasser som er tilgjengelige på språket:

  • Statisk nestede klasser
  • Ikke-statiske nestede klasser
  • Lokale klasser
  • Anonyme klasser

I de neste avsnittene skal vi diskutere hver av disse i detalj.

2. Statisk nestede klasser

Her er noen få punkter å huske på statiske nestede klasser:

  • Som med statiske medlemmer, tilhører disse klassen deres og ikke en forekomst av klassen
  • De kan ha alle typer tilgangsmodifikatorer i erklæringen
  • De har bare tilgang til statiske medlemmer i den vedlagte klassen
  • De kan definere både statiske og ikke-statiske medlemmer

La oss se hvordan vi kan erklære en statisk nestet klasse:

offentlig klasse Vedlegg {privat statisk int x = 1; offentlig statisk klasse StaticNested {private void run () {// metodeimplementering}} @ Test public void test () {Enclosing.StaticNested nested = new Enclosing.StaticNested (); nestet.run (); }}

3. Ikke-statiske nestede klasser

Deretter er det noen få poeng å huske på ikke-statiske nestede klasser:

  • De kalles også indre klasser
  • De kan ha alle typer tilgangsmodifikatorer i erklæringen
  • Akkurat som forekomstvariabler og metoder, er indre klasser assosiert med en forekomst av den omsluttende klassen
  • De har tilgang til alle medlemmer av klassen som inngår, uavhengig av om de er statiske eller ikke-statiske
  • De kan bare definere ikke-statiske medlemmer

Slik kan vi erklære en indre klasse:

offentlig klasse Ytre {offentlig klasse indre {// ...}}

Hvis vi erklærer en nestet klasse med en modifikator statisk, så er det en statisk medlem en. Ellers er det en indre klasse. Selv om forskjellen syntaktisk bare er et enkelt nøkkelord (dvs. statisk), semantisk er det en stor forskjell mellom slike nestede klasser. Forekomster av indre klasse er bundet til de vedlagte klassene, og derfor har de tilgang til medlemmene sine. Vi bør være oppmerksomme på dette problemet når vi velger om vi skal gjøre en nestet klasse til en indre.

For å instansiere en indre klasse, må vi først instansiere den omsluttende klassen.

La oss se hvordan vi kan gjøre det:

Ytre ytre = ny Ytre (); Ytre. Indre indre = ytre. Ny indre ();

I de neste underavsnittene skal vi vise noen spesielle typer indre klasser.

3.1. Lokale klasser

Lokale klasser er en spesiell type indre klasser - der klassen er definert i en metode eller omfangsblokk.

La oss se noen få poeng å huske på denne typen klasser:

  • De kan ikke ha tilgangsmodifikatorer i erklæringen
  • De har tilgang til både statiske og ikke-statiske medlemmer i den vedlagte sammenhengen
  • De kan bare definere instansmedlemmer

Her er et raskt eksempel:

offentlig klasse NewEnclosing {void run () {class Local {void run () {// method implementation}} Local local = new Local (); local.run (); } @Test offentlig ugyldig test () {NewEnclosing newEnclosing = new NewEnclosing (); newEnclosing.run (); }}

3.2. Anonyme klasser

Anonyme klasser kan brukes til å definere en implementering av et grensesnitt eller en abstrakt klasse uten å måtte lage en gjenbrukbar implementering.

La oss liste opp noen punkter å huske på anonyme klasser:

  • De kan ikke ha tilgangsmodifikatorer i erklæringen
  • De har tilgang til både statiske og ikke-statiske medlemmer i den vedlagte sammenhengen
  • De kan bare definere instansmedlemmer
  • De er den eneste typen nestede klasser som ikke kan definere konstruktører eller utvide / implementere andre klasser eller grensesnitt

For å definere en anonym klasse, la oss først definere en enkel abstrakt klasse:

abstrakt klasse SimpleAbstractClass {abstrakt ugyldig kjøre (); }

La oss nå se hvordan vi kan definere en anonym klasse:

public class AnonymousInnerUnitTest {@Test public void whenRunAnonymousClass_thenCorrect () {SimpleAbstractClass simpleAbstractClass = new SimpleAbstractClass () {void run () {// method implementation}}; simpleAbstractClass.run (); }}

For mer informasjon kan vi finne nyttig opplæringen vår om anonyme klasser i Java.

4. Skyggelegging

Erklæringen fra medlemmene i en indre klasse skygger de fra den omsluttende klassen hvis de har samme navn.

I dette tilfellet dette nøkkelord refererer til forekomster av den nestede klassen, og medlemmene av den ytre klassen kan refereres til ved å bruke navnet på den ytre klassen.

La oss se et raskt eksempel:

offentlig klasse NewOuter {int a = 1; statisk int b = 2; offentlig klasse InnerClass {int a = 3; statisk sluttint b = 4; offentlig ugyldig kjøring () {System.out.println ("a =" + a); System.out.println ("b =" + b); System.out.println ("NewOuterTest.this.a =" + NewOuter.this.a); System.out.println ("NewOuterTest.b =" + NewOuter.b); System.out.println ("NewOuterTest.this.b =" + NewOuter.this.b); }} @Test offentlig ugyldig test () {NewOuter outer = new NewOuter (); NewOuter.InnerClass inner = outer.new InnerClass (); inner.run (); }}

5. Serialisering

For å unngå a java.io.NotSerializableException mens vi prøver å serieisere en nestet klasse, bør vi:

  • Erklær den nestede klassen som statisk
  • Gjør både den nestede klassen og den vedlagte klassen implementere Serialiserbar

6. Konklusjon

I denne artikkelen har vi sett hva nestede klasser er og deres forskjellige typer. Vi tok også en titt på hvordan feltvisibilitet og tilgangsmodifikatorer varierer mellom de forskjellige typene.

Som alltid kan den fulle implementeringen av denne opplæringen finnes på GitHub.