CodeGym /Curs Java /Java Multithreading /Clase interioare anonime și exemple

Clase interioare anonime și exemple

Java Multithreading
Nivel , Lecţie
Disponibil
Clase interioare anonime și exemple - 1

"Bună, Amigo!"

— Dar deja am salutat, Ellie!

"Hei, nu te certa cu mătușa ta. În secolul 31, dacă nu te-ai mai văzut pe cineva de mai bine de jumătate de oră, se obișnuiește să te saluti din nou. Așa că nu-mi da atitudinea ta!"

„Oricum, este timpul pentru un alt subiect interesant: reproducerea robotului!”

"O_O."

„Glumesc, noul subiect sunt clasele interioare anonime .”

„În Java, uneori există situații în care veți avea nevoie de o clasă pentru a moșteni mai multe clase. Deoarece Java nu acceptă moștenirea multiplă, au rezolvat această problemă folosind clase interne: în clasa noastră, declarăm o clasă interioară și facem moștenește orice clasă pe care trebuie să o moștenim. Iată un exemplu:"

Exemplu de clasă interioară care moștenește clasa Thread
class Tiger extends Cat
{
 public void tigerRun()
 {
  .....
 }

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

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

„Hai să cercetăm un alt exemplu:”

Avem nevoie de o subclasă a clasei Thread pentru a-i suprascrie metoda de rulare.”

„De aceea, în clasa Tiger am declarat clasa interioară TigerThread , care moștenește Thread și suprascrie metoda run.

„Pentru comoditate, am definit două metode în clasa Tiger: tigerRun și startTiger (care sunt analoge cu metodele de rulare și pornire ale Thread."

„În metoda tigerStart, creăm un obiect TigerThread și invocăm metoda lui start()”.

„JVM-ul va crea un fir nou care va începe să ruleze când este apelată metoda de rulare a lui TigerThread .”

„Această metodă apelează apoi metoda noastră de rulare : tigerRun ”.

„Am mai lucrat cu fire, așa că pare simplu.”

„Trebuie să denumim metodele tigerRun și tigerStart?”

„Nu, i-am fi putut chema să alerge și să înceapă, dar am vrut, de asemenea, să demonstrez că nu moștenim Thread. O explicație ar fi putut fi mai confuză.”

„OK. Atunci cred că am înțeles. Dar dacă tigerStart este apelat a doua oară, vom crea și vom începe un al doilea obiect Thread. Asta nu înseamnă că vom avea „un tigru care rulează pe două fire diferite”? "

"Ei bine, nu ești ascuțit! Ai dreptate și asta nu e bine. Hai să rescriem codul așa:"

Cod
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();
  }
 }
}

"Nu este perfect. Totuși nu poți apela de două ori o astfel de metodă. Dar de data aceasta, cel puțin nu vom crea un al doilea thread și nu vom face să pară că totul este în regulă."

"Așa este. A doua oară când pornește un Tigru, vei primi o excepție."

— Deja observ greşelile mai bine decât tine, Ellie!

"Da, te descurci grozav. Atunci hai să trecem la clasele interioare anonime."

„Rețineți câteva aspecte ale codului de mai sus:”

1) Am moștenit clasa Thread, dar nu am implementat practic niciun cod acolo. „A fost mai degrabă „trebuia să moștenim clasa Thread” decât „am moștenit-o pentru a o extinde”.

2) Va fi creat un singur obiect TigerThread.

Cu alte cuvinte, am scris o grămadă de cod doar pentru a suprascrie o metodă și a crea un obiect.

Îți amintești cum vorbeam despre invenția constructorilor?

Înainte de constructori După constructori
TigerThread thread = new TigerThread();

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

„Văd că codul a devenit mai compact, dar nu prea înțeleg ce se întâmplă”.

„Putem combina patru lucruri într-unul singur:”

1) declararea unei clase derivate

2) depășirea metodei

3) declararea unei variabile

4) crearea unei instanțe a unei clase derivate.

„De fapt, ceea ce facem este să combinăm două operații: declararea unei clase derivate și crearea unei instanțe a acelei clase.”

Fără clasă anonimă Cu clasa anonima
Cat tiger = new Tiger();

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

„Să explorăm din nou sintaxa:”

Declarația unei variabile Thread
Thread thread = new Thread();
Declarația unei variabile al cărei tip este „o clasă anonimă care moștenește Thread”
Thread thread = new Thread()
{

};

"Rețineți că nu definim pur și simplu o nouă clasă. Creăm o variabilă - există un punct și virgulă la sfârșit!"

„Și dacă vrem să suprascriem metoda de rulare, atunci trebuie să scriem asta:”

Declarația unei variabile Thread
Thread thread = new Thread()
{
 public void run()
  {
   System.out.println("new run-method");
  }
};

"Te prinzi repede. Bravo!"

"Multumesc. Ce se intampla daca avem nevoie de alte metode care nu fac parte din clasa Thread?"

„Le poți scrie”.

„Deși anonim, aceasta este o clasă interioară cu drepturi depline:”

Cod Java Descriere
Thread thread = new Thread()
{
  public void run()
  {
   printHi();
  }

  public void printHi()
  {
   System.out.println("Hi!");
  }
};	 
Roșu: cod pentru crearea variabilei.

Verde: cod pentru crearea obiectului.

Albastru: cod pentru clasa derivată anonimă.

— O clasă interioară cu drepturi depline?

„Deci pot folosi variabilele clasei exterioare?”

"Absolut."

— Și pot să transmit ceva constructorului?

„Da, dar numai argumentele pentru constructorul superclasei:”

Clasă Instanța unei clase interioare anonime
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);
  }
};

"Nu putem adăuga propriii parametri la constructorul altcuiva. Dar putem folosi variabilele clasei exterioare, ceea ce compensează frumos acest neajuns."

„Dacă mai trebuie să adaug alți parametri la constructor?”

„Atunci declarați o clasă interioară obișnuită (non-anonimă) și folosiți-o.”

— Corect, aproape că am uitat de asta.

"Ce se întâmplă dacă declar o variabilă statică? Ar face ca clasa anonimă să devină o clasă imbricată statică mai degrabă decât o clasă interioară? Cu alte cuvinte, îi va lipsi o referință la clasa exterioară?"

"Nu. Ar fi o clasă interioară anonimă. Uită-te la aceste exemple."

Cu clasa anonima Fără clasă anonimă
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();
 }
}

"Înțeleg. Numai variabila statică ar fi statică, nu clasa."

"Da."

„De fapt, compilatorul creează clase interne pentru toate clasele interne anonime. Aceste clase sunt de obicei numite «1», «2», «3», etc."

Comentarii
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION