CodeGym /Java Blogu /Rastgele /Java'da OOP kavramları
John Squirrels
Seviye
San Francisco

Java'da OOP kavramları

grupta yayınlandı
Java'nın en güçlü yönlerinden biri nesne yönelimli programlamadır (OOP). Bu dilin bu kadar popüler olmasının ve her büyüklükteki proje için çok uygun olmasının nedeni budur. Nesne yönelimli programlama nedir? Bu sihir değil, ama gerçekten içine girersen büyülü görünebilir. OOP, yazılımınızı nasıl oluşturacağınızla ilgilidir. Bu, yazılımı etkin bir şekilde geliştirmek ve kullanmak için Java nesneleri arasında bazı özel etkileşimler ve ilişkiler oluşturmanıza izin veren bir kavram veya daha doğrusu Java'daki bir grup oop kavramıdır. Java'da OOP kavramları - 1Klasik OOP, 3 + 1 ana kavramları içerir. Klasiklerle başlayalım.

Nesne

Java nesnelerinin yanı sıra gerçek dünya nesnelerinin iki özelliği vardır: durum ve davranış.

Örneğin, bir İnsan nesnesinin durumu (ad, cinsiyet, uyuyor ya da değil…) ve davranışı (Java çalışıyor, yürüyor, konuşuyor…) vardır. Herhangi bir Java nesnesi, durumunu alanlarda saklar ve davranışını yöntemler aracılığıyla gösterir.

kapsülleme

Veri kapsülleme, dahili verileri dış dünyadan gizlemek ve bunlara yalnızca halka açık yöntemlerle erişmektir. Bu ne anlama gelir? Hangi veriler? Kimden saklanıyor? Gizleme, bir sınıfın veri üyelerine (alanlarına) doğrudan erişimi kısıtlamak anlamına gelir.

Java'da nasıl çalışır:

  1. Alanlar özel yapılır
  2. Bir sınıftaki her alan iki özel yöntem alır: bir alıcı ve bir ayarlayıcı. Getter yöntemleri, alanın değerini döndürür. Ayarlayıcı yöntemleri, alanın değerini dolaylı ama izin verilen bir şekilde değiştirmenize izin verir.

Java kodunda kapsülleme örneği:


public class Student {
private int age;
private String name;

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

public class Test{
public static void main(String[] args) {
Student firstStudent = new Student();
firstStudent.setName("John");
// The name field is private, so you can no longer do this:  firstStudent.name = "John"; 
}
}

Neden kapsülleme kullanmalısınız?

Ana sebep, kodunuzu değiştirmeyi kolaylaştırmaktır. Bir hokey okulu için bir başvurunuz olduğunu ve öğrencinin okula kaydolduğu zamanki adını ve yaşını saklayan iki alana sahip bir HockeyStudent sınıfı olduğunu hayal edin . Bunun gibi bir şey:

public class HockeyStudent {
public String name;
public  int ageOfEnrollment;
}
ageOfEnrollment alanı herkese açıktır, alıcı veya ayarlayıcı yoktur... Bu sınıf diğer birçok sınıf tarafından kullanılır ve bazı geliştiriciler tek bir int alanının yeterli olmadığına karar verene kadar her şey yolundaydı. Bir kohorttaki bazı hokey oyuncuları akranlarından neredeyse bir yaş büyüktür, bu nedenle onları doğdukları aya göre iki gruba ayırmak daha uygun olacaktır. Bu nedenle, ageOfEnrollment alanı bir int dizisine (int[][]) değiştirilmelidir : ilk sayı tam yıl, ikincisi ay içindir. Şimdi Student sınıfını kullanan tüm kodları yeniden düzenlemeniz gerekiyor ! Ama eğer kayıt yaşınızalan özeldir ve alıcılarınız ve ayarlayıcılarınız vardır, o zaman her şey daha kolaydır. Bir öğrencinin yaşını ayarlama gereksinimi değişirse, setAgeOfEnrollment() ayarlayıcı yöntemindeki mantığı güncellemeniz yeterlidir ve sınıflarınız Student'ı sorunsuz bir şekilde kullanmaya devam edebilir! Bu örnek biraz yapmacık ama umarım kapsüllemeyi kullanmanın neden harika bir fikir olduğunu açıklamaktadır.

Miras

Bu ilke, herhangi bir pratik deneyim olmadan bile anlaşılması daha kolaydır. Kendinizi tekrar etmeyin (DRY) miras kavramının sloganı olabilir. Kalıtım, ana sınıfın alanlarını ve yöntemlerini yeniden tanımlamadan devralan bir alt sınıf oluşturmanıza olanak tanır. Elbette, alt sınıftaki ana sınıfın alanlarını ve yöntemlerini geçersiz kılabilirsiniz, ancak bu bir gereklilik değildir. Dahası, alt sınıfa yeni durumlar ve davranışlar ekleyebilirsiniz. Üst sınıflara bazen üst sınıflar veya temel sınıflar denir ve alt sınıflar, alt sınıflar olarak bilinir. Java'nın extends anahtar sözcüğü, kodda kalıtım ilkesini uygulamak için kullanılır.

Java'da nasıl çalışır:

  1. Üst sınıfı oluşturun.
  2. Extends anahtar sözcüğünü kullanarak alt sınıfı oluşturun .
  3. Child sınıfının yapıcısında, ebeveynin alanlarını ayarlamak için super(parentField1, parentField2, ...) yöntemini kullanın.

Yapıcı, yeni oluşturulan bir nesneyi başlatmak için kullanılan özel bir yöntemdir. Bir yapıcı, sınıf adıyla aynı ada sahiptir. İki tür oluşturucu vardır: varsayılan (arg içermeyen oluşturucu) ve parametreli oluşturucu. Bir sınıfın en az bir kurucusu olmalıdır (başka kurucular tanımlanmamışsa, varsayılan kurucuya sahiptir) ve bunlardan çok sayıda olabilir.

Her yeni nesne oluşturduğunuzda, onun yapıcısını çağırırsınız. Yukarıdaki örnekte, bunu şu satırda yaparsınız:


Student firstStudent = new Student();

Student sınıfının varsayılan kurucusunu çağırmak için new anahtar sözcüğünü kullanırsınız : tudent() .

Bazı kurallar:

  1. Bir sınıfın yalnızca bir ebeveyni olabilir.
  2. Bir üst sınıfın birçok alt sınıfı olabilir.
  3. Bir alt sınıfın kendi alt sınıfları olabilir.

Java kodunda kalıtım örneği

Bir Telefon sınıfı oluşturalım .

public class Phone {
    int price;
    double weight;

// Constructor
public Phone(int price, double weight) {
        this.price = price;
        this.weight = weight;
    }

    void orderPhone(){
        System.out.println("Ordering phone...");
    }
}
Tabii ki, farklı telefon türleri var, bu yüzden iki alt sınıf oluşturalım: biri Android telefonlar için ve ikincisi iPhone'lar için. Ardından, ebeveynin sahip olmadığı bazı alanlar ve yöntemler ekleyeceğiz. Ve üst sınıfın sahip olduğu alanları başlatmak üzere yapıcıları çağırmak için super()' i kullanacağız .

Java'da kalıtım örneği


public class Android extends Phone {

// Some new fields     
String androidVersion;
int screenSize;

    String secretDeviceCode;

// Constructor 
    public Android(int price, double weight, String androidVersion, int screenSize, String secretDeviceCode) {
        super(price, weight); // Android inherits Phone’s fields

        //this - reference to the current object
        //super - reference to the parent object

        this.androidVersion = androidVersion;
        this.screenSize = screenSize;
        this.secretDeviceCode = secretDeviceCode;
    }

	// New Android-specific method, does not exist in the Phone class 
    void installNewAndroidVersion() {
        System.out.println("installNewAndroidVersion invoked...");

    }

}

public class IPhone extends Phone {
   
    boolean fingerPrint;

    public IPhone(int price, double weight, boolean fingerPrint) {
        super(price, weight);
        System.out.println("IPhone constructor was invoked...");
        this.fingerPrint = fingerPrint;
    }

    void deleteIPhoneFromDb() {
        System.out.println("deleteIPhoneFromDb invoked...");
    }

@Override // This is about polymorphism, see below
void orderPhone(){
        System.out.println("Ordering my new iPhone and deleting the old one...");
    }
}
Tekrar etmek gerekirse: Java'da kalıtım, bir sınıfı üst sınıfın alanlarını ve yöntemlerini miras alan alt sınıflarla genişletmenize izin verir. Kodun yeniden kullanılabilirliğini sağlamanın mükemmel bir yoludur.

polimorfizm

Polimorfizm, bir nesnenin dönüşme, farklı biçimler alma veya daha doğrusu farklı şekillerde hareket etme yeteneğidir. Java'da, polimorfizm genellikle bir alt sınıf nesnesine atıfta bulunmak için bir üst sınıf referansı kullanıldığında meydana gelir.

Bunun anlamı ve Java'da nasıl çalıştığı:

Java'da polimorfizm nedir? Genel olarak bu, aynı yöntem adını farklı amaçlar için kullanabileceğiniz anlamına gelir. Java'da iki tür çok biçimlilik vardır: yöntem geçersiz kılma (dinamik çok biçimlilik) ve yöntem aşırı yükleme (statik çok biçimlilik).

Yöntem geçersiz kılma

Bir alt sınıfta bir üst sınıfın yöntemini geçersiz kılarak onu farklı şekilde çalışmaya zorlayabilirsiniz. Play() yöntemiyle bir Müzisyen üst sınıfı oluşturalım .

Java kodunda polimorfizm örneği


   public class Musician {
    String name;
    int age;

    // Default constructor
    public Musician() {
    }

    // Parameterized constructor
    public Musician(String name, int age) {
        this.name = name;
        this.age = age;
    }

    void play() {
        System.out.println("I am playing my instrument...");
    }
}
Farklı müzisyenler farklı enstrümanlar kullanır. İki alt sınıf oluşturalım: Pianist ve Violinist . Polimorfizm sayesinde, her biri kendi play() yöntemi sürümünü yürütür . Geçersiz kılırken, @Override ek açıklamasını kullanabilirsiniz , ancak bu gerekli değildir.

public class Pianist extends Musician {
    
    String favoritePianoType;

    public Pianist(String name, int age, String favoritePianoType) {
        super(name, age);
        this.favoritePianoType = favoritePianoType;
    }


    @Override
void play(){
        System.out.println("I am playing the piano...");
    }
}
Kemancı solist veya orkestra üyesi olabilir. play() yöntemimizi geçersiz kılarken bunu göz önünde bulunduralım .

public class Violinist extends Musician { 
    boolean isSoloist; 

public Violinist(String name, int age, boolean isSoloist) {
            super(name, age);
            this.isSoloist = isSoloist;
        }


    @Override
void play(){
if (isSoloist) 
        System.out.println("I am playing the violin solo...");
else 
System.out.println("I am playing the violin in an orchestra...");

    }
}
Önceden oluşturulmuş sınıfların her birinin bir örneği olan üç nesne oluşturacağımız bir Demo sınıfı oluşturalım . Bakalım ne sonuçlar alacağız.

public class Demo {
  public static void main(String[] args) {
  Musician musician = new Musician();
  Violinist violinist = new Violinist("John", 32, true);
  Pianist pianist = new Pianist("Glen", 30, "Acoustic"); 

  System.out.println("Musician said:");
  musician.play();
  System.out.println("Violinist said:");
  violinist.play();
  System.out.println("Pianist said:");
  pianist.play();
    }
}
İşte elde ettiklerimiz:

Musician said:
I am playing my instrument...
Violinist said:
I am playing the violin solo…
Pianist said:
I am playing the piano...
Her kemancı ve piyanist müzisyendir ama her müzisyen viyolacı veya piyanist değildir. Bu, yeni bir tane oluşturmanız gerekmiyorsa, müzisyenin çalma yöntemini kullanabileceğiniz anlamına gelir. Veya super anahtar sözcüğünü kullanarak ebeveynin yöntemini çocuktan çağırabilirsiniz . Bunu Pianist'in kodunda yapalım:

public class Pianist extends Musician {

    String favoritePianoType;
    
    @Override
    void play(){
        super.play();
        System.out.println("I am playing the piano...");
    }
}
Şimdi Demo sınıfında main() metodumuzu çağıralım . İşte sonuç:

Musician said:
I am playing my instrument...
Violinist said:
I am playing the violin solo...
Pianist said:
I am playing my instrument...
I am playing the piano...

Yöntem aşırı yükleme

Yöntem aşırı yükleme, aynı sınıfta aynı ada sahip çeşitli yöntemlerin kullanılması anlamına gelir. Parametrelerinin sayısı, sırası veya türleri açısından farklı olmalıdırlar. Bir piyanistin akustik piyano ve elektrikli piyano çalabildiğini varsayalım. Elektro çalmak için müzisyenin elektriğe ihtiyacı vardır. İki farklı play() metodu oluşturalım . Akustik piyano için parametresiz ilki ve elektriğin mevcut olup olmadığını gösteren parametreli ikincisi.

public class Pianist extends Musician {

    String name;
    int age;
    String favoritePianoType;

    @Override
    void play(){
        super.play();
        System.out.println("I am playing the piano...");
    }
    void play(boolean isElectricity){
        if (isElectricity) {
            System.out.println("The electricity is on.");
            System.out.println("I am playing the piano...");
        }
        else System.out.println("I can't play this without electricity.");
    }
}
Bu arada, birinci play() yöntemini ikinci play(boolean) yöntemi içinde şu şekilde kullanabilirsiniz :

void play(boolean isElectricity){
        if (isElectricity) {
            System.out.println("The electricity is on.");
            play();
        }
        else System.out.println("I can't play this without electricity.");
    }
Aşırı yüklememizi göstermek için Demo sınıfımıza bazı satırlar ekleyelim :

public class Demo {
    public static void main(String[] args) {

        Musician musician = new Musician();
        Violinist violinist = new Violinist("John", 23, true);
        Pianist pianist = new Pianist("Glen", 30, "Acoustic"); 

        System.out.println("Musician said:");
        musician.play();
        System.out.println("Violinist said:");
        violinist.play();
        System.out.println("Pianist said:");
        pianist.play();
        System.out.println("The pianist will now try the electric piano:");
        pianist.play(true);
        System.out.println("The electricity has been shut off. Now when trying the electric piano, the pianist says:");
        pianist.play(false);
    }
}
İşte sonuç:

Musician said:
I am playing my instrument...
Violinist said:
I am playing the violin solo...
Pianist said:
I am playing my instrument...
I am playing the piano...
The pianist will now try the electric piano:
The electricity is on.
I am playing my instrument...
I am playing the piano...
The electricity has been shut off. Now when trying the electric piano, the pianist says:
I can't play this without electricity.
Java, parametrelerine ve nesne türüne göre hangi yöntemin kullanılması gerektiğini bilir. Bu polimorfizmdir.

Soyutlama

Bir sınıf tanımladığımızda, bir şeyin modelini oluşturmaya çalışıyoruz. Örneğin, farklı yarış arabalarıyla MyRacer adlı bir video oyunu yazdığımızı varsayalım. Bir oyuncu bunlardan birini seçebilir ve daha sonra güncelleyebilir veya farklı bir tane satın alabilir. Yani… Araba nedir? Bir araba oldukça karmaşık bir şeydir, ancak (bir sürüş simülatörünün aksine) bir yarış video oyunu yaratmaya çalışıyorsak, içerdiği binlerce dişli ve contayı tanımlamamıza gerek yoktur. Modeline, azami hızına, manevra kabiliyetine, fiyatına, rengine ihtiyacımız var… Ve belki de bu kadar yeter. Bu bizim oyunumuz için bir araba modeli. Daha sonra MyRacer 2'de yol tutuşunu etkileyen lastikler eklemeye karar verdiğimizi varsayalım. Burada model farklı çünkü daha fazla detay ekledik. İzin vermek' s, veri soyutlamayı bir nesnenin yalnızca önemli (veya gerekli) özelliklerini tanımlama ve ilgisiz ayrıntıları göz ardı etme süreci olarak tanımlar. Farklı soyutlama seviyeleri vardır. Örneğin, bir otobüste yolcuysanız, otobüsünüzün nasıl göründüğünü ve nereye gittiğini bilmeniz gerekir, ancak nasıl sürüleceğini bilmenize gerek yoktur. Bir otobüs şoförüyseniz, yeni bir otobüsün nasıl oluşturulacağını bilmenize gerek yok - sadece onu nasıl süreceğinizi bilmeniz gerekiyor. Ama otobüs üreticisi iseniz soyutlamanın bir alt seviyesine inmeniz gerekiyor çünkü otobüs tasarımının detayları sizin için çok önemli. Umarım ne söylemek istediğimi anladın. otobüsünüzün neye benzediğini ve nereye gittiğini bilmeniz gerekir, ancak onu nasıl kullanacağınızı bilmeniz gerekmez. Bir otobüs şoförüyseniz, yeni bir otobüsün nasıl oluşturulacağını bilmenize gerek yok - sadece onu nasıl süreceğinizi bilmeniz gerekiyor. Ama otobüs üreticisi iseniz soyutlamanın bir alt seviyesine inmeniz gerekiyor çünkü otobüs tasarımının detayları sizin için çok önemli. Umarım ne söylemek istediğimi anladın. otobüsünüzün neye benzediğini ve nereye gittiğini bilmeniz gerekir, ancak onu nasıl kullanacağınızı bilmeniz gerekmez. Bir otobüs şoförüyseniz, yeni bir otobüsün nasıl oluşturulacağını bilmenize gerek yok - sadece onu nasıl süreceğinizi bilmeniz gerekiyor. Ama otobüs üreticisi iseniz soyutlamanın bir alt seviyesine inmeniz gerekiyor çünkü otobüs tasarımının detayları sizin için çok önemli. Umarım ne söylemek istediğimi anladın.

Java'da nasıl çalışır:

Java'da veya daha doğrusu OOP'de en düşükten (en spesifik) en yükseğe (en soyut) dört soyutlama düzeyi oluşturalım.
  1. En düşük soyutlama düzeyi, belirli bir nesnedir. Belirli bir sınıfa ait bir dizi özelliğe sahip bir varlıktır. Belirli alan değerleri vardır

  2. Nesne oluşturmak için bir şablon bir sınıftır. Benzer özelliklere ve iç yapıya sahip bir dizi nesnenin açıklamasıdır.

  3. Soyut bir sınıf, bir sınıflar kümesinin özelliklerinin soyut bir açıklamasıdır (diğer sınıflar tarafından kalıtım için bir şablon görevi görür). Yüksek düzeyde soyutlamaya sahiptir, bu nedenle doğrudan soyut bir sınıftan nesne oluşturmak imkansızdır. Nesne oluşturmak için yalnızca soyut sınıfların alt sınıfları kullanılabilir. Soyut bir sınıf, uygulamalı yöntemler içerebilir, ancak bu bir gereklilik değildir.

  4. Arayüz, yalnızca soyut genel yöntemleri ve statik sabit alanları (son statik) içeren Java programlama dili yapısının bir yapısıdır. Başka bir deyişle, nesne oluşturmak için ne soyut sınıflar ne de arayüzler kullanılabilir.

BTW, Java 8 veya sonraki sürümlerde arabirimler yalnızca soyut yöntemlere ve sabitlere değil, aynı zamanda varsayılan ve statik yöntemlere de sahip olabilir. Java'da bir arayüz bir davranışı tanımlarken, bir hiyerarşi oluşturmak için soyut bir sınıf kullanılır. Bir arabirim birden çok sınıf tarafından uygulanabilir.

Java kodunda bir arayüz örneği


interface Human {
	public void struggle();
	public void protect();
}

interface Vulcan {
	int angleOfPointyEars; 
	public void turnOffEmotions(boolean isOn);
	public void telepathy();
}
Birden fazla arayüz uygulayabilirsiniz

The Spock class implements Human and Vulcan {
public void struggle() {
System.out.println("I am struggling...");
}
	public void protect() {
System.out.println("You are under my protection!”);
}
public void turnOffEmotions(boolean isOn){
If (isOn) {
System.out.println("I am turning off my emotions.");
isOn= !isOn;
}
}
	public void telepathy() {
System.out.println("Connecting to your brain...");
}

}
Başlangıç ​​düzeyindeki öğrenciler için bu, Java'daki nesne yönelimli programlamanın tüm ana kavramlarını kapsar. 4 ana OOP ilkesinin yanı sıra, Java ayrıca ilişkilendirme, toplama ve düzenlemeye sahiptir. Bunlara "ek OOP ilkeleri" diyebilirsiniz. Kendi ayrı makalelerini hak ediyorlar.
Yorumlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION