Anonim iç sınıflar ve örnekler - 1

"Merhaba, Amigo!"

"Ama biz zaten merhaba dedik, Ellie!"

"Hey, halanla tartışma. 31. yüzyılda, birini yarım saatten fazla görmemişsen, tekrar merhaba demek adettendir. Bu yüzden bana tavrını söyleme!"

"Her neyse, başka bir ilginç konunun zamanı geldi: robot üretimi!"

"O_O."

"Şaka yapıyorum, yeni konu anonim iç sınıflar ."

"Java'da bazen birkaç sınıfı miras almak için bir sınıfa ihtiyaç duyacağınız durumlar vardır. Java çoklu kalıtımı desteklemediğinden, bu sorunu iç sınıfları kullanarak çözmüşlerdir: sınıfımızda, bir iç sınıf ilan ederiz ve yaparız. devralmak için ihtiyacımız olan sınıfı devralır. İşte bir örnek:"

Thread sınıfını miras alan bir iç sınıf örneği
class Tiger extends Cat
{
 public void tigerRun()
 {
  .....
 }

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

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

"Başka bir örneğe bakalım:"

Çalıştırma yöntemini geçersiz kılmak için Thread sınıfının bir alt sınıfına ihtiyacımız var."

"İşte bu yüzden Tiger sınıfında , Thread'i devralan ve run yöntemini geçersiz kılan TigerThread iç sınıfını ilan ettik.

"Kolaylık olması için Tiger sınıfında iki yöntem tanımladık: tigerRun ve startTiger (Thread'in çalıştırma ve başlatma yöntemlerine benzerler).

"tigerStart yönteminde, bir TigerThread nesnesi oluşturuyoruz ve onun start() yöntemini çağırıyoruz."

"JVM, TigerThread'in çalıştırma yöntemi çağrıldığında çalışmaya başlayacak yeni bir iş parçacığı oluşturacak ."

"Bu yöntem daha sonra çalıştırma yöntemimizi çağırır : tigerRun ."

"Daha önce iş parçacıklarıyla çalıştım, bu yüzden bu basit görünüyor."

"Yöntemleri tigerRun ve tigerStart olarak adlandırmak zorunda mıyız?"

"Hayır, onlara koş ve başla diyebilirdik ama ayrıca Thread'i miras almadığımızı da göstermek istedim. Bir açıklama daha kafa karıştırıcı olabilirdi."

"Tamam. O zaman sanırım anladım. Ama TigerStart ikinci kez çağrılırsa, ikinci bir Thread nesnesi oluşturup başlatacağız. Bu, «bir kaplanın iki farklı iş parçacığında koştuğu» anlamına gelmez mi? "

"Pekala, keskin değil misin! Haklısın ve bu iyi değil. Kodu şu şekilde yeniden yazalım:"

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

"Tam olarak mükemmel değil. Yine de böyle bir yöntemi iki kez çağıramazsınız. Ama bu sefer en azından ikinci bir iş parçacığı oluşturup her şey yolundaymış gibi göstermeyeceğiz."

"Doğru. Bir Tiger'ı ikinci kez başlattığınızda, bir istisna ile karşılaşacaksınız."

"Hataları şimdiden senden daha iyi görüyorum, Ellie!"

"Evet, harika gidiyorsun. O halde anonim dahili sınıflara geçelim."

"Yukarıdaki kodun çeşitli yönlerine dikkat edin:"

1) Thread sınıfını devraldık, ancak orada neredeyse hiç kod uygulamadık. "Bu, "genişletmek için onu devraldık"tan çok "Thread sınıfını miras almamız gerekiyordu" idi.

2) Yalnızca bir TigerThread nesnesi oluşturulacak.

Başka bir deyişle, yalnızca bir yöntemi geçersiz kılmak ve bir nesne oluşturmak için bir sürü kod yazdık.

İnşaatçıların icadı hakkında nasıl konuştuğumu hatırlıyor musun?

Yapıcılardan önce inşaatçılardan sonra
TigerThread thread = new TigerThread();

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

"Kodun daha derli toplu hale geldiğini görüyorum ama ne olduğunu pek anlamıyorum."

"Dört şeyi bir araya getirebiliriz:"

1) türetilmiş bir sınıfın bildirimi

2) yöntem geçersiz kılma

3) bir değişkenin bildirimi

4) türetilmiş bir sınıfın örneğinin oluşturulması.

"Aslında, yaptığımız şey iki işlemi birleştirmek: türetilmiş bir sınıf bildirmek ve o sınıfın bir örneğini yaratmak."

Anonim sınıf olmadan Anonim sınıf ile
Cat tiger = new Tiger();

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

"Sözdizimini tekrar keşfedelim:"

Bir Thread değişkeninin bildirimi
Thread thread = new Thread();
Türü "Thread'i miras alan anonim bir sınıf" olan bir değişkenin bildirimi
Thread thread = new Thread()
{

};

"Sadece yeni bir sınıf tanımlamadığımıza dikkat edin. Bir değişken yaratıyoruz - sonunda bir noktalı virgül var!"

"Ve eğer run yöntemini geçersiz kılmak istiyorsak, şunu yazmamız gerekir:"

Bir Thread değişkeninin bildirimi
Thread thread = new Thread()
{
 public void run()
  {
   System.out.println("new run-method");
  }
};

"Çabuk anladın. Aferin!"

"Teşekkürler. Ya Thread sınıfının parçası olmayan başka yöntemlere ihtiyacımız olursa?"

"Onları yazabilirsin."

"Anonim olmasına rağmen, bu tam teşekküllü bir iç sınıftır:"

java kodu Tanım
Thread thread = new Thread()
{
  public void run()
  {
   printHi();
  }

  public void printHi()
  {
   System.out.println("Hi!");
  }
};	 
Kırmızı: değişkeni oluşturmak için kod.

Yeşil: nesneyi oluşturmak için kod.

Mavi: anonim türetilmiş sınıf için kod.

"Tam teşekküllü bir iç sınıf mı?"

"Yani dış sınıfın değişkenlerini kullanabilir miyim?"

"Kesinlikle."

"Ve inşaatçıya bir şey iletebilir miyim?"

"Evet, ancak yalnızca üst sınıfın yapıcısının argümanları:"

Sınıf Anonim bir iç sınıf örneği
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);
  }
};

"Başka birinin yapıcısına kendi parametrelerimizi ekleyemeyiz. Ancak dış sınıfın değişkenlerini kullanabiliriz, bu da bu eksikliği güzel bir şekilde telafi eder."

"Yapıcıya gerçekten başka parametreler eklemem gerekirse ne olur?"

"O zaman sıradan (anonim olmayan) bir iç sınıf ilan edin ve onu kullanın."

"Doğru, neredeyse onu unutuyordum."

"Ya statik bir değişken bildirirsem? Bu, anonim sınıfı bir iç sınıf yerine statik bir iç sınıf haline getirir mi? Başka bir deyişle, dış sınıfa bir referansı olmayacak mı?"

"Hayır. Anonim bir iç sınıf olurdu. Şu örneklere bak."

Anonim sınıf ile Anonim sınıf olmadan
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();
 }
}

"Anlıyorum. Yalnızca statik değişken statik olur, sınıf değil."

"Evet."

"Aslında, derleyici tüm anonim iç sınıflar için iç sınıflar oluşturur. Bu sınıflar genellikle "1", "2", "3" vb. olarak adlandırılır."