1. Pegasus

OOP'nin üçüncü ilkesine daha derin bir göz atalım : kalıtım . Bu, sık sık kullanacağınız çok ilginç bir konudur. Acemi olanlar için programlama sihirden ayırt edilemez. O halde ilginç bir benzetme ile başlayalım...;

Diyelim ki uçan bir at yaratmak isteyen bir sihirbazsınız. Bir yandan, bir pegasus yaratmayı deneyebilirsiniz. Fakat pegasi doğada bulunmadığı için bu çok zor olacaktır. Kendiniz çok şey yapmanız gerekecek. Bir atı alıp kanatlarını oluşturmak çok daha kolay.

Programlamada bu işleme "miras" denir. Çok karmaşık bir sınıf yazmanız gerektiğini varsayalım. Sıfırdan kod yazmak ve ardından hataları aramak için her şeyi uzun süre test etmek uzun zaman alır. Neden zor yoldan gidelim? Böyle bir sınıfın zaten var olup olmadığına bakmak daha iyidir.

Yöntemleri ihtiyacınız olan işlevselliğin %80'ini uygulayan bir sınıf bulduğunuzu varsayalım. Bundan sonra onunla ne yapacaksın? Kodunu sınıfınıza kopyalayabilirsiniz. Ancak bu çözümün birkaç dezavantajı vardır:

  1. Bulduğunuz sınıf zaten bayt kodunda derlenmiş olabilir ve kaynak koduna erişiminiz olmayabilir.
  2. Sınıfın kaynak kodu mevcut, ancak başka birinin kodunun 6 satırını bile kullandığınız için birkaç milyar dava edilebilecek bir şirkette çalışıyorsunuz. Ve sonra işvereniniz sizi dava edecek.
  3. Büyük miktarda kodun gereksiz tekrarı. Ek olarak, harici bir sınıfın yazarı, içinde bir hata bulur ve düzeltirse, hataya sahip olmaya devam edersiniz.

Daha zarif bir çözüm var ve orijinal sınıfın koduna yasal erişim elde etmeyi gerektirmiyor. Java'da, o sınıfı basitçe sınıfınızın ebeveyni olarak ilan edebilirsiniz. Bu, o sınıfın kodunu kendi kodunuza eklemekle eşdeğer olacaktır. Sınıfınız, üst sınıfın tüm verilerini ve tüm yöntemlerini görecektir. Örneğin, şunu yapabilirsiniz: "at"ı miras alırız ve sonra "pegasus" elde etmek için "kanatları" ekleriz.


2. Ortak temel sınıf

Miras başka amaçlar için de kullanılabilir. Diyelim ki çok benzer on sınıfınız var. Aynı verilere ve yöntemlere sahipler. Özel bir temel sınıf oluşturabilir, verileri (ve ilişkili yöntemleri) bu temel sınıfa taşıyabilir ve bu on sınıfı torun olarak ilan edebilirsiniz. Başka bir deyişle, her sınıfta, üst sınıfının bu temel sınıf olduğunu belirtin.

Soyutlamanın avantajlarının yalnızca yan kapsülleme boyunca ortaya çıkması gibi , polimorfizm kullanıldığında kalıtımın avantajları da çok artar. Ama bunu biraz sonra öğreneceksin. Bugün kalıtımı kullanmanın birkaç örneğine bakacağız.

Satranç taşları

Bir insan kullanıcıyla satranç oynayan bir program yazdığımızı varsayalım. Buna göre, parçaları temsil edecek sınıflara ihtiyacımız var. Hangi sınıflar olurdu?

Hiç satranç oynadıysanız, bariz cevap Şah, Vezir, Fil, At, Kale ve Piyon'dur.

Ancak sınıfların yine de her bir parça hakkında bilgi depolaması gerekir. Örneğin, x ve y koordinatları ve parçanın değeri. Sonuçta, bazı parçalar diğerlerinden daha değerlidir.

Ayrıca taşlar farklı hareket ediyor, bu da sınıfların farklı davranışlar uygulayacağı anlamına geliyor. Bunları sınıflar olarak şu şekilde tanımlayabilirsiniz:

class King
{
   int x;
   int y;
   int worth;

   void kingMove()
   {
     // Code that decides
     // how to move
     // the king
   }
}
class Queen
{
   int x;
   int y;
   int worth;

   void queenMove()
   {
     // Code that decides
     // how to move
     // the queen
   }
}
class Rook
{
   int x;
   int y;
   int worth;

   void rookMove()
   {
     // Code that decides
     // how to move
     // the rook
   }
}
class Knight
{
   int x;
   int y;
   int worth;

   void knightMove()
   {
     // Code that decides
     // how to move
     // the knight
   }
}
class Bishop
{
   int x;
   int y;
   int worth;

   void bishopMove()
   {
     // Code that decides
     // how to move
     // the bishop
   }
}
class Pawn
{
   int x;
   int y;
   int worth;

   void pawnMove()
   {
     // Code that decides
     // how to move
     // the pawn
   }
}

Bu, satranç taşlarının çok ilkel bir tanımıdır.

Ortak temel sınıf

Ve işte kod miktarını azaltmak için kalıtımı nasıl kullanabileceğiniz. Ortak metotları ve verileri ortak bir sınıfa getirebiliriz. Onu arayacağız ChessItem. Sınıf herhangi bir satranç taşına karşılık gelmediğinden, 'nin nesneleriniChessItem class yaratmanın bir anlamı yoktur . Bununla birlikte, sınıf çok yararlı olacaktır:

class King extends ChessItem
{
   void kingMove()
   {
     // Code that decides
     // how to move the king
   }
}
class Queen extends ChessItem
{
   void queenMove()
   {
     // Code that decides
     // how to move the queen
   }
}
class Rook extends ChessItem
{
   void rookMove()
   {
     // Code that decides
     // how to move the rook
   }
}
class ChessItem
{
   int x;
   int y;
   int worth;
}
class Knight extends ChessItem
{
   void knightMove()
   {
     // Code that decides
     // how to move the knight
   }
}
class Bishop extends ChessItem
{
   void bishopMove()
   {
     // Code that decides
     // how to move the bishop
   }
}
class Pawn extends ChessItem
{
   void pawnMove()
   {
     // Code that decides
     // how to move the pawn
   }
}

Bu, benzer nesneler için kodu basitleştirmenin harika bir yoludur. Faydalar, özellikle projede binlerce farklı nesne ve yüzlerce sınıf olduğunda fark edilir. Bu nedenle, uygun şekilde seçilen üst (temel) sınıflar, yalnızca mantığı büyük ölçüde basitleştirmenize değil, aynı zamanda kodu on kat azaltmanıza da olanak tanır.


3. Sınıf kalıtımı —extends

Peki bir sınıfı miras almak için ne gerekiyor? Bir sınıfın diğerini miras alması için, alt sınıf bildiriminden sonra anahtar kelimeyi yazmanız extendsve ardından üst sınıfın adını yazmanız gerekir. Genellikle şöyle bir şeye benziyor:

class Descendant extends Parent

Descendant sınıfını bildirirken yazmanız gereken şey budur. Bu arada, bir sınıf yalnızca bir sınıfı miras alabilir.

Resimde, bir ineğin bir domuzu, bir tavuğu miras alan bir yumurtayı miras aldığını görüyoruz. Sadece bir ebeveyn! Böyle bir kalıtım her zaman mantıklı değildir. Ancak sahip olduğunuz tek şey bir domuz olduğunda ve gerçekten bir ineğe ihtiyacınız olduğunda, programcılar genellikle domuzdan bir inek yapma dürtüsüne karşı koyamazlar.

Java'nın çoklu kalıtımı yoktur: bir sınıf iki sınıfı miras alamaz. Her sınıfın yalnızca bir ebeveyn sınıfı olabilir. Üst sınıf belirtilmezse, üst sınıf Object.

Bununla birlikte, Java'nın birden çok arabirim mirası vardır. Bu, sorunu biraz azaltır. Arayüzlerden biraz sonra bahsedeceğiz ama şimdilik kalıtımı keşfetmeye devam edelim.