Anonyme indre klasser og eksempler - 1

"Hej, Amigo!"

"Men vi har allerede sagt hej, Ellie!"

"Hey, lad være med at skændes med din tante. I det 31. århundrede, hvis du ikke har set nogen i mere end en halv time, er det kutyme at sige hej igen. Så giv mig ikke din holdning!"

"I hvert fald er det tid til endnu et interessant emne: robotreproduktion!"

"O_O."

"Bare for sjov, det nye emne er anonyme indre klasser ."

"I Java er der nogle gange situationer, hvor du skal bruge en klasse for at arve flere klasser. Da Java ikke understøtter multipel nedarvning, har de løst dette problem ved hjælp af indre klasser: i vores klasse erklærer vi en indre klasse og laver den arver den klasse, vi skal have den til at arve. Her er et eksempel:"

Eksempel på en indre klasse, der arver trådklassen
class Tiger extends Cat
{
 public void tigerRun()
 {
  .....
 }

 public void startTiger()
 {
  TigerThread thread = new TigerThread();
  thread.start();
 }

 class TigerThread extends Thread
 {
  public void run()
  {
   tigerRun();
  }
 }
}

"Lad os grave i et andet eksempel:"

Vi har brug for en underklasse af Thread-klassen for at tilsidesætte dens kørselsmetode."

"Det er derfor, vi i Tiger-klassen erklærede den indre TigerThread- klasse, som arver Thread og tilsidesætter kørselsmetoden.

"For nemheds skyld definerede vi to metoder i Tiger-klassen: tigerRun og startTiger (som er analoge med Threads løbe- og startmetoder."

"I tigerStart-metoden opretter vi et TigerThread- objekt og kalder dets start()-metode."

"JVM'et vil oprette en ny tråd, der begynder at køre, når TigerThreads kørselsmetode kaldes."

"Denne metode kalder så vores kørselsmetode : tigerRun ."

"Jeg har arbejdet med tråde før, så det virker ligetil."

"Skal vi navngive metoderne tigerRun og tigerStart?"

"Nej, vi kunne have kaldt dem løbe og starte, men jeg ville også gerne demonstrere, at vi ikke arver Tråd. En forklaring kunne have været mere forvirrende."

"OK. Så tror jeg, jeg forstår det. Men hvis tigerStart kaldes en anden gang, opretter og starter vi et andet Thread-objekt. Betyder det ikke, at vi har «én tiger kørende på to forskellige tråde»? "

"Nå, er du ikke skarp! Du har ret, og det er ikke godt. Lad os omskrive koden sådan her:"

Kode
class Tiger extends Cat
{
 public void tigerRun()
 {
  .....
 }

 public void startTiger()
 {
  thread.start();
 }

 private TigerThread thread = new TigerThread();

 private class TigerThread extends Thread
 {
  public void run()
  {
   tigerRun();
  }
 }
}

"Det er ikke helt perfekt. Du kan stadig ikke kalde sådan en metode to gange. Men denne gang vil vi i det mindste ikke oprette en anden tråd og få det til at virke som om alt er i orden."

"Det er rigtigt. Anden gang en Tiger startes, får du en undtagelse."

"Jeg opdager allerede fejl bedre end dig, Ellie!"

"Ja, du gør det godt. Så lad os gå videre til anonyme indre klasser."

"Bemærk flere aspekter af koden ovenfor:"

1) Vi arvede Thread-klassen, men implementerede praktisk talt ingen kode der. "Det var mere "vi skulle arve trådklassen" snarere end "vi arvede den for at udvide den".

2) Kun ét TigerThread-objekt vil blive oprettet.

Med andre ord skrev vi en hel masse kode bare for at tilsidesætte én metode og oprette ét objekt.

Kan du huske, hvordan jeg talte om opfindelsen af ​​konstruktører?

Før konstruktører Efter konstruktører
TigerThread thread = new TigerThread();

private class TigerThread extends Thread
{
 public void run()
 {
  tigerRun();
 }
}
Thread thread = new Thread()
{
 public void run()
 {
  tigerRun();
 }
};

"Jeg kan se, at koden blev mere kompakt, men jeg forstår ikke helt, hvad der sker."

"Vi kan kombinere fire ting til én:"

1) erklæring om en afledt klasse

2) metode tilsidesættelse

3) deklaration af en variabel

4) oprettelse af en instans af en afledt klasse.

"Faktisk er det, vi gør, at kombinere to operationer: at erklære en afledt klasse og skabe en forekomst af den klasse."

Uden anonym klasse Med anonym klasse
Cat tiger = new Tiger();

class Tiger extends Cat
{
}
Cat tiger = new Cat()
{
};

"Lad os udforske syntaksen igen:"

Erklæring af en trådvariabel
Thread thread = new Thread();
Erklæring af en variabel, hvis type er «en anonym klasse, der arver tråden»
Thread thread = new Thread()
{

};

"Bemærk, at vi ikke blot definerer en ny klasse. Vi opretter en variabel – der er et semikolon i slutningen!"

"Og hvis vi vil tilsidesætte kørselsmetoden, skal vi skrive dette:"

Erklæring af en trådvariabel
Thread thread = new Thread()
{
 public void run()
  {
   System.out.println("new run-method");
  }
};

"Du fanger hurtigt. Godt gået!"

"Tak. Hvad hvis vi har brug for andre metoder, der ikke er en del af trådklassen?"

"Du kan skrive dem."

"Selvom det er anonymt, er dette en fuldgyldig indre klasse:"

Java kode Beskrivelse
Thread thread = new Thread()
{
  public void run()
  {
   printHi();
  }

  public void printHi()
  {
   System.out.println("Hi!");
  }
};
Rød: kode til oprettelse af variablen.

Grøn: kode til oprettelse af objektet.

Blå: kode for den anonymt afledte klasse.

"En fuldgyldig indre klasse?"

"Så jeg kan bruge variablerne fra den ydre klasse?"

"Absolut."

"Og jeg kan give noget videre til konstruktøren?"

"Ja, men kun argumenterne for superklassens konstruktør:"

klasse Eksempel på en anonym indre klasse
class Cat
{
 int x, y;
 Cat(int x, int y)
 {
  this.x = x;
  thix.y = y;
 }
}
Cat cat = new Cat(3,4)
{
  public void print()
  {
   System.out.println(x+" "+y);
  }
};

"Vi kan ikke tilføje vores egne parametre til en andens konstruktør. Men vi kan bruge variablerne i den ydre klasse, hvilket fint kompenserer for denne mangel."

"Hvad hvis jeg stadig virkelig har brug for at tilføje andre parametre til konstruktøren?"

"Så erklærer du en almindelig (ikke-anonym) indre klasse og brug den."

"Godt, det glemte jeg næsten."

"Hvad hvis jeg erklærer en statisk variabel? Ville det få den anonyme klasse til at blive en statisk indlejret klasse i stedet for en indre klasse? Med andre ord, vil den mangle en reference til den ydre klasse?"

"Nej. Det ville være en anonym indre klasse. Se på disse eksempler."

Med anonym klasse Uden anonym klasse
Thread thread = new Thread()
{
  public void run()
  {
   tigerRun();
  }
};
TigerThread thread = new TigerThread();

private class TigerThread extends Thread
{
 public void run()
 {
  tigerRun();
 }
}
static Thread thread = new Thread()
{
  public void run()
  {
   tigerRun();
  }
};
static TigerThread thread = new TigerThread();

private class TigerThread extends Thread
{
 public void run()
 {
  tigerRun();
 }
}

"Jeg kan se. Kun den statiske variabel ville være statisk, ikke klassen."

"Ja."

"Faktisk opretter compileren indre klasser for alle anonyme indre klasser. Disse klasser hedder normalt «1», «2», «3» osv.«