MERHABA! Java'daki soyut sınıflardan bahsedelim .Java'daki soyut sınıfların somut örnekleri - 1

Sınıflar neden "soyut" olarak adlandırılıyor?

Muhtemelen soyutlamanın ne olduğunu hatırlıyorsunuzdur - daha önce tartışmıştık :) Unuttuysanız endişelenmeyin. Unutmayın, sınıfları tasarlarken ve nesneleri oluştururken yalnızca varlığın ana özelliklerini temsil etmeniz ve ikincil olanları atmanız gerektiğini söyleyen bir OOP ilkesidir . Örneğin, bir sınıf tasarlıyorsak SchoolTeacher, boy muhtemelen bir öğretmen için gerekli bir özellik olmayacaktır. Aslında bu özellik bir öğretmen için önemli değildir. Ama eğer bir sınıf oluşturuyorsak BasketballPlayer, boy en önemli özelliklerden biri olacaktır. Soyut bir sınıfgelecekteki bir grup sınıf için en soyut, "kaba iş parçası" dır. İş parçası doğrudan kullanılamaz - çok "kaba". Ancak gelecekteki sınıfların - soyut sınıfın soyundan gelenlerin - sahip olacağı belirli karakteristik durum ve davranışları tanımlar.

Java'daki soyut sınıf örnekleri

Arabalarla ilgili basit bir örneği ele alalım:

public abstract class Car {

   private String model;
   private String color;
   private int maxSpeed;
  
   public abstract void gas();

   public abstract void brake();

   public String getModel() {
       return model;
   }

   public void setModel(String model) {
       this.model = model;
   }

   public String getColor() {
       return color;
   }

   public void setColor(String color) {
       this.color = color;
   }

   public int getMaxSpeed() {
       return maxSpeed;
   }

   public void setMaxSpeed(int maxSpeed) {
       this.maxSpeed = maxSpeed;
   }
}
En basit soyut sınıf böyle görünüyor. Gördüğünüz gibi özel bir şey yok :) Neden buna ihtiyacımız olabilir? İlk olarak, ihtiyacımız olan varlığın en soyut tanımını sağlar - bir araba. Soyut anahtar kelime burada bir şey ifade ediyor. Gerçek dünyada "sadece bir araba" diye bir şey yoktur. Kamyonlar, yarış arabaları, sedanlar, coupe'ler ve SUV'lar var. Soyut sınıfımız, daha sonra belirli araba sınıfları oluşturmak için kullanacağımız bir "plan" dır.

public class Sedan extends Car {
  
   @Override
   public void gas() {
       System.out.println("The sedan is accelerating!");
   }

   @Override
   public void brake() {
       System.out.println("The sedan is slowing down!");
   }
  
}
Birçok yönden bu, kalıtımla ilgili derslerde bahsettiğimiz şeye benzer. Ancak bu durumda Caryöntemleri soyut olmayan bir sınıfımız oldu. Ancak böyle bir çözümün, soyut sınıflarda sabitlenen birkaç dezavantajı vardır. Her şeyden önce, bir soyut sınıfın örneği oluşturulamaz:

public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // Error! The Car class is abstract!
   }
}
Java'nın yaratıcısı bu "özelliği" bilerek yaptı. Bir kez daha unutmayın: soyut bir sınıf, yalnızca gelecekteki "normal" sınıflar için bir plandır . Bir planın kopyalarına ihtiyacınız yok, değil mi? Benzer şekilde, soyut bir sınıfın örneklerini oluşturmaya gerek yoktur :) Ve eğer Carsınıf soyut değilse, o zaman kolayca örneklerini oluşturabiliriz:

public class Car {

   private String model;
   private String color;
   private int maxSpeed;
  
   public void go() {
       // ...some logic
   }

   public  void brake() {
       // ...some logic
   }
}


public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // This is okay. The car is created.
   }
}
Şu anda programımızda bir tür anlaşılmaz araba var. Kamyon değil, yarış arabası değil, sedan da değil ama ne olduğu tam olarak belli değil. Gerçekte var olmayan "sadece bir araba". Aynı örnek hayvanlar için de verilebilir. Programınızın Animalnesneleri (" sadece hayvanlar ") olduğunu hayal edin. Ne tür olduğu, hangi familyaya ait olduğu, hangi özelliklere sahip olduğu belli değil. Bir programda birini görmek garip olurdu. Doğada "sadece hayvanlar" yoktur. Yalnızca köpekler, kediler, tilkiler, köstebekler vb. Soyut sınıflar bizi " sadece nesnelerden " kurtarır. Bize temel durumu ve davranışı verirler. Örneğin, tüm arabaların bir modeli , rengi ve azami hızı olmalıdır.ve ayrıca gaz ve fren uygulayabilmelidirler . Bu kadar. Bu, ihtiyacınız olan sınıfları tasarlamak için daha sonra kullanacağınız genel bir soyut taslaktır. Not: soyut sınıftaki iki yöntem de soyuttur , yani hiçbir uygulamaları yoktur. Sebep aynı: soyut sınıflar "sadece arabalar" için "varsayılan davranışlar" yaratmaz. Sadece her arabanın ne yapması gerektiğini gösteriyorlar. Bununla birlikte, varsayılan davranışa ihtiyacınız varsa, yöntemleri soyut bir sınıfta uygulayabilirsiniz. Java bunu yasaklamaz:

public abstract class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public void gas() {
       System.out.println("Accelerating!");
   }

   public abstract void brake();
  
   // Getters and setters
}


public class Sedan extends Car {

   @Override
   public void brake() {
       System.out.println("The sedan is slowing down!");
   }

}

public class Main {

   public static void main(String[] args) {

       Sedan sedan = new Sedan();
       sedan.gas();
   }
}
Konsol çıktısı:
Accelerating!
Gördüğünüz gibi, soyut sınıfta bir yöntemi uyguladık, diğerini uygulamadık. Sonuç olarak, sınıfımızın davranışı Sedaniki bölüme ayrılmıştır: yöntemini çağırırsak gas(), davranış soyut üst sınıftan "çekilir" ve yöntemi sınıfta Caruygularız . Bu çok kullanışlı ve esnektir. Ama sınıfımız artık o kadar soyut değil, değil mi ? Ne de olsa, aslında yöntemlerin yarısını uyguladı. Gerçek şu ki - ve bu çok önemli bir özelliktir - yöntemlerinden biri bile soyut olan bir sınıf soyuttur.brake()Sedan. İki yöntemden biri veya bin yöntemden biri - fark etmez. Hatta hiçbirini soyut bırakmadan tüm yöntemleri uygulayabiliriz. Sonuç, herhangi bir soyut yöntem içermeyen soyut bir sınıf olacaktır. Bu prensipte mümkündür - derleyici herhangi bir hata üretmeyecektir - ancak bunu yapmamak daha iyidir, çünkü soyut kelimesini anlamından mahrum eder. Programcı arkadaşlarınız da bunu görünce çok şaşıracaklar :/ Bununla birlikte, bir yöntem soyut olarak işaretlenirse, her alt sınıf onu uygulamalı veya soyut olarak bildirilmelidir. Aksi halde derleyici hata verecektir.. Elbette her sınıf yalnızca bir soyut sınıfı miras alabilir, dolayısıyla soyut ve normal sınıflar arasında kalıtım açısından bir fark yoktur. Soyut bir sınıf mı yoksa normal bir sınıf mı miras aldığımız önemli değil - yalnızca bir üst sınıf olabilir.

Java neden çoklu sınıf mirasına sahip değil?

Java'da çoklu kalıtım olmadığını daha önce söylemiştik, ancak nedenini gerçekten araştırmadık. Şimdi bunu yapmaya çalışalım. Gerçek şu ki, eğer Java birden fazla kalıtıma sahip olsaydı, o zaman alt sınıflar hangi davranışın seçileceğine karar veremezdi. Diyelim ki iki sınıfımız var: Toasterve NuclearBomb:

public class Toaster {
  
  
 public void on() {

       System.out.println("The toaster is on. We're toasting!");
   }
  
   public void off() {

       System.out.println("The toaster is off!");
   }
}


public class NuclearBomb {

   public void on() {

       System.out.println("Boom!");
   }
}
Gördüğünüz gibi, her iki sınıfın da bir on()yöntemi var. Tost makinesi için yöntem tost yapmaya başlar, ancak nükleer bomba söz konusu olduğunda bir patlama başlatır. Uh-oh :/ Şimdi arada bir şey yaratmaya karar verdiğinizi (bana nedenini sorma!) hayal edin. İşte sınıfınız: MysteriousDevice! Bu kod elbette çalışmaz. Bunu basitçe "ne olabilirdi" örneği olarak sunuyoruz:

public class MysteriousDevice extends Toster, NuclearBomb {

   public static void main(String[] args) {
      
       MysteriousDevice mysteriousDevice = new MysteriousDevice();
       mysteriousDevice.on(); // And what should happen here? Will we get toast or a nuclear apocalypse?
   }
}
Neye sahip olduğumuza bir bakalım. Gizemli cihaz, aynı anda hem Toaster hem de NuclearBomb'dan geliyor. İkisinin de bir on()yöntemi var. on()Sonuç olarak, bir nesneyi çağırırsak hangi uygulamanın yürütülmesi gerektiği açık değildir MysteriousDevice. Nesne anlamayacak. Üstelik NuclearBomb'un bir off()yöntemi yok, bu yüzden doğru tahmin edemezsek, cihazı kapatmak imkansız olacak. Java'daki soyut sınıfların somut örnekleri - 2Hangi davranışın yürütülmesi gerektiği belirsiz olduğunda bu "yanlış anlama", Java'nın yaratıcılarının çoklu kalıtımı reddetmesinin tam nedenidir. Bununla birlikte, Java sınıflarının birçok arayüzü uygulayabileceğini öğreneceksiniz.