Softmush.com, teknoloji, yazılım ve dijital dünyaya dair derinlemesine içeriklerle bilgiye ulaşmanın güvenilir adresi. - Softmush.com
“ Söz konusu olan vatansa, gerisi teferruat. ”
Mustafa K. Atatürk
PHP Dilinde Öntanımlı Arayüzler ve Soyut Sınıflar Kullanımı

PHP Dilinde Öntanımlı Arayüzler ve Soyut Sınıflar Kullanımı

Nesne yönelimli programlama (OOP) prensipleri, modern yazılım geliştirmede kodun yapısını, okunabilirliğini ve sürdürülebilirliğini sağlamak için kritik öneme sahiptir. PHP, bu prensipleri desteklemek adına arayüzler (interfaces) ve soyut sınıflar (abstract classes) gibi güçlü yapılar sunar. Bu yapılar, sınıflar arasında belirli davranış sözleşmeleri tanımlayarak veya ortak bir temel sağlayarak esnek ve genişletilebilir sistemler oluşturulmasına olanak tanır. Bu makale, PHP'deki arayüzlerin ve soyut sınıfların detaylı kullanımını, sözdizimini ve pratik örneklerini ele alacaktır.


Temel Sözdizimi


PHP'de arayüzler ve soyut sınıflar, belirli anahtar kelimeler kullanılarak tanımlanır ve diğer sınıflar tarafından uygulanır veya miras alınır. Aşağıda temel sözdizimleri gösterilmektedir.



ozellik = $ozellik;
    }

    // Soyut metot: Gövdesi yoktur, alt sınıflar tarafından uygulanmalıdır.
    abstract public function soyutMetot(): string;

    // Somut metot: Gövdesi vardır, alt sınıflar tarafından miras alınır veya geçersiz kılınabilir.
    public function somutMetot(): string {
        return "Somut metot çalıştı: " . $this->ozellik;
    }
}

// Arayüz Uygulayan Sınıf
class SomutSinifA implements ArayuzAdi {
    public function metotBir(string $parametre): bool {
        // Metot uygulamasını buraya yazın
        return true;
    }

    public function metotIki(): void {
        // Metot uygulamasını buraya yazın
    }
}

// Soyut Sınıfı Miras Alan Sınıf
class SomutSinifB extends SoyutSinifAdi {
    public function soyutMetot(): string {
        return "Soyut metot SomutSinifB tarafından uygulandı: " . $this->ozellik;
    }
}

?>

Detaylı Açıklama


Arayüzler ve soyut sınıflar, farklı senaryolar için tasarlanmış olsalar da, her ikisi de soyutlama ve polimorfizm prensiplerini destekler.


Arayüzler (Interfaces)


Bir arayüz, bir sınıfın sahip olması gereken metotları tanımlayan bir "sözleşme" görevi görür. Arayüzler, bir sınıfın dış dünyaya hangi davranışları sergileyeceğini belirtir, ancak bu davranışların nasıl uygulanacağını belirtmez.


  • Tanım: Bir arayüz interface anahtar kelimesiyle tanımlanır. İçerisinde yalnızca metot imzaları ve sabitler bulunabilir.


  • Metotlar: Arayüzdeki tüm metotlar otomatik olarak public ve soyuttur (yani gövdeleri yoktur). Metot imzaları, parametre tiplerini ve dönüş tiplerini (PHP 7.0 ve sonrası) içerebilir.


  • Özellikler: Arayüzler herhangi bir özellik (member variable) tanımlayamaz.


  • Sabitler: Arayüzler sabitler tanımlayabilir. Bu sabitlere ArayuzAdi::SABIT_ADI şeklinde erişilebilir.


  • Uygulama: Bir sınıf, bir arayüzü implements anahtar kelimesiyle uygular. Bir sınıf birden fazla arayüzü uygulayabilir (örneğin: class MyClass implements InterfaceA, InterfaceB).


  • Zorunluluk: Bir arayüzü uygulayan sınıf, arayüzdeki tüm metotları belirtilen imzalarla (public olarak) uygulamak zorundadır. Aksi takdirde bir fatal hata oluşur.


Soyut Sınıflar (Abstract Classes)


Soyut sınıflar, bir veya daha fazla soyut metot içerebilen veya içermeyen, doğrudan örneği oluşturulamayan sınıflardır. Genellikle, bir grup ilgili sınıf için ortak bir temel (base class) sağlamak amacıyla kullanılırlar.


  • Tanım: Bir soyut sınıf abstract class anahtar kelimesiyle tanımlanır.


  • Örneklenme: Soyut sınıfların doğrudan bir örneği (objesi) oluşturulamaz. Yalnızca alt sınıfları (concrete classes) örneklenebilir.


  • Metotlar: Soyut sınıflar hem soyut metotlar (abstract public function metotAdi();) hem de somut metotlar (gövdesi olan metotlar) içerebilir. Soyut metotların gövdesi yoktur ve alt sınıflar tarafından uygulanması zorunludur. Somut metotlar ise alt sınıflar tarafından miras alınır ve isteğe bağlı olarak geçersiz kılınabilir.


  • Erişim Belirleyiciler: Soyut metotlar public veya protected olabilir ancak private olamaz. Alt sınıflar soyut metotları uygularken aynı veya daha az kısıtlayıcı bir erişim belirleyici kullanamazlar (yani protected soyut metot public olarak uygulanabilir ama private olarak uygulanamaz).


  • Özellikler: Soyut sınıflar özellikler (member variables) tanımlayabilir. Bu özellikler public, protected veya private olabilir.


  • Kalıtım: Bir sınıf, bir soyut sınıfı extends anahtar kelimesiyle miras alır. PHP tekli kalıtımı desteklediği için bir sınıf yalnızca bir soyut sınıfı miras alabilir.


  • Zorunluluk: Soyut bir sınıfı miras alan alt sınıf, soyut sınıftaki tüm soyut metotları uygulamak zorundadır. Aksi takdirde, alt sınıfın kendisi de soyut olarak tanımlanmalıdır.


Pratik Kullanım Örnekleri


Aşağıdaki örnekler, arayüzlerin ve soyut sınıfların gerçek dünya senaryolarında nasıl kullanılabileceğini göstermektedir.


Örnek 1: Arayüz Kullanımı - Loglama Sistemi


Farklı loglama mekanizmalarını (dosyaya, veritabanına, konsola) destekleyen bir sistem düşünelim. Tüm loglama sınıflarının aynı log() metoduna sahip olmasını bir arayüz ile sağlayabiliriz.



filePath = $filePath;
    }

    public function log(string $message): void {
        file_put_contents($this->filePath, date('Y-m-d H:i:s') . " - " . $message . PHP_EOL, FILE_APPEND);
        echo "Dosyaya loglandı: " . $message . "
"; } } class DatabaseLogger implements Logger { public function log(string $message): void { // Veritabanına loglama işlemleri burada yapılır echo "Veritabanına loglandı: " . $message . "
"; } } class ConsoleLogger implements Logger { public function log(string $message): void { echo "Konsola loglandı: " . $message . "
"; } } // Loglama işlemini gerçekleştiren bir fonksiyon function processLog(Logger $logger, string $message): void { $logger->log($message); } // Kullanım $fileLogger = new FileLogger('application.log'); $dbLogger = new DatabaseLogger(); $consoleLogger = new ConsoleLogger(); processLog($fileLogger, "Uygulama başlatıldı."); processLog($dbLogger, "Kullanıcı girişi başarılı."); processLog($consoleLogger, "Hata oluştu."); // Çıktı: // Dosyaya loglandı: Uygulama başlatıldı. // Veritabanına loglandı: Kullanıcı girişi başarılı. // Konsola loglandı: Hata oluştu. ?>

Bu örnekte, Logger arayüzü, loglama yeteneğine sahip tüm sınıfların log() metodunu içermesi gerektiğini garanti eder. Bu sayede, processLog() fonksiyonu herhangi bir Logger tipindeki objeyi kabul edebilir, bu da esneklik ve kod tekrarı önleme sağlar.


Örnek 2: Soyut Sınıf Kullanımı - Ödeme Geçitleri


Bir e-ticaret uygulamasında farklı ödeme geçitleri (Kredi Kartı, PayPal, Havale) olabilir. Bu geçitlerin hepsinin ortak bazı işlevleri (örneğin işlem ücreti hesaplama) ve kendine özgü işlevleri (ödeme onayı) bulunur. Ortak işlevleri soyut bir sınıfta toplayabiliriz.



transactionFeeRate = $rate;
    }

    // Ortak somut metot
    public function calculateFee(float $amount): float {
        return $amount * $this->transactionFeeRate;
    }

    // Soyut metot: Her alt sınıfın kendi ödeme işlemini tanımlaması gerekir
    abstract public function processPayment(float $amount): bool;

    // Soyut metot: Her alt sınıfın kendi geri ödeme işlemini tanımlaması gerekir
    abstract public function refundPayment(string $transactionId): bool;
}

class CreditCardGateway extends PaymentGateway {
    public function __construct() {
        parent::__construct(0.025); // %2.5 işlem ücreti
    }

    public function processPayment(float $amount): bool {
        echo "Kredi kartı ile " . $amount . " TL ödeme işlemi başlatıldı. Ücret: " . $this->calculateFee($amount) . " TL.
"; // Kredi kartı API'si ile ödeme mantığı return true; } public function refundPayment(string $transactionId): bool { echo "Kredi kartı işlemi " . $transactionId . " için geri ödeme yapıldı.
"; // Kredi kartı API'si ile geri ödeme mantığı return true; } } class PayPalGateway extends PaymentGateway { public function __construct() { parent::__construct(0.03); // %3 işlem ücreti } public function processPayment(float $amount): bool { echo "PayPal ile " . $amount . " TL ödeme işlemi başlatıldı. Ücret: " . $this->calculateFee($amount) . " TL.
"; // PayPal API'si ile ödeme mantığı return true; } public function refundPayment(string $transactionId): bool { echo "PayPal işlemi " . $transactionId . " için geri ödeme yapıldı.
"; // PayPal API'si ile geri ödeme mantığı return true; } } // Kullanım $creditCard = new CreditCardGateway(); $paypal = new PayPalGateway(); $creditCard->processPayment(100.00); $paypal->processPayment(250.00); $creditCard->refundPayment("CC12345"); $paypal->refundPayment("PP67890"); // Çıktı: // Kredi kartı ile 100 TL ödeme işlemi başlatıldı. Ücret: 2.5 TL. // PayPal ile 250 TL ödeme işlemi başlatıldı. Ücret: 7.5 TL. // Kredi kartı işlemi CC12345 için geri ödeme yapıldı. // PayPal işlemi PP67890 için geri ödeme yapıldı. ?>

Burada PaymentGateway soyut sınıfı, tüm ödeme geçitleri için ortak olan calculateFee() metodunu ve her geçidin kendi içinde uygulaması gereken processPayment() ve refundPayment() soyut metotlarını tanımlar. Bu, kod tekrarını azaltır ve ödeme geçidi eklemeyi standartlaştırır.


Örnek 3: Arayüz ve Soyut Sınıfın Birlikte Kullanımı


Bir soyut sınıfın bir arayüzü uygulaması ve bu soyut sınıfı miras alan somut sınıfların arayüzdeki metotları uygulaması da mümkündür. Bu, hem bir sözleşme sağlamak hem de belirli bir varsayılan uygulama veya ortak davranış seti sunmak için güçlü bir kombinasyondur.



sender = $sender;
    }

    // Soyut metot: Arayüzden miras alınır ve alt sınıflar tarafından uygulanmalıdır
    abstract public function send(string $recipient, string $message): bool;

    // Ortak bir somut metot: Tüm bildirim sistemlerinde bulunabilir
    public function getSender(): string {
        return $this->sender;
    }
}

// Somut sınıf: E-posta ile bildirim gönderen bir sistem
class EmailNotifier extends AbstractNotifier {
    public function send(string $recipient, string $message): bool {
        echo "E-posta gönderiliyor: Kimden: " . $this->getSender() . ", Kime: " . $recipient . ", Mesaj: '" . $message . "'
"; // Gerçek e-posta gönderme mantığı buraya gelir return true; } } // Somut sınıf: SMS ile bildirim gönderen bir sistem class SmsNotifier extends AbstractNotifier { public function send(string $recipient, string $message): bool { echo "SMS gönderiliyor: Kimden: " . $this->getSender() . ", Kime: " . $recipient . ", Mesaj: '" . $message . "'
"; // Gerçek SMS gönderme mantığı buraya gelir return true; } } // Kullanım $emailNotifier = new EmailNotifier("info@example.com"); $smsNotifier = new SmsNotifier("5551234567"); $emailNotifier->send("john.doe@example.com", "Hesabınız başarıyla oluşturuldu."); $smsNotifier->send("5559876543", "Siparişiniz yola çıktı."); // Çıktı: // E-posta gönderiliyor: Kimden: info@example.com, Kime: john.doe@example.com, Mesaj: 'Hesabınız başarıyla oluşturuldu.' // SMS gönderiliyor: Kimden: 5551234567, Kime: 5559876543, Mesaj: 'Siparişiniz yola çıktı.' ?>

Bu örnekte, Notifier arayüzü tüm bildirim sistemlerinin send() metoduna sahip olmasını sağlayan bir sözleşme sunar. AbstractNotifier soyut sınıfı ise bu arayüzü uygulayarak send() metodunu soyut bırakır, ancak tüm bildirim sistemleri için ortak bir gönderen özelliği ve getSender() metodu sağlar. EmailNotifier ve SmsNotifier sınıfları, AbstractNotifier'ı miras alarak hem Notifier arayüzünün gereksinimlerini yerine getirir hem de ortak getSender() metodunu kullanır.


Önemli Notlar


  • Amaç Farkı: Arayüzler "ne yapılması gerektiğini" tanımlayan sözleşmelerdir. Soyut sınıflar ise "kim olduğunu" ve "neyin ortak olduğunu" tanımlayan kısmi uygulamalardır.


  • Çoklu Uygulama vs. Tekli Kalıtım: Bir sınıf birden fazla arayüzü uygulayabilir (implements InterfaceA, InterfaceB), bu PHP'de çoklu kalıtımı simüle etmenin bir yoludur. Ancak bir sınıf yalnızca bir soyut sınıfı miras alabilir (extends AbstractClass).


  • Metot Erişim Belirleyicileri: Arayüz metotları her zaman public olmak zorundadır. Soyut sınıf metotları ise public veya protected olabilir, ancak private olamaz.


  • Özellikler (Properties): Arayüzler özellik tanımlayamaz. Soyut sınıflar ise özellik tanımlayabilir ve bu özellikler public, protected veya private olabilir.


  • Sabitler: Hem arayüzler hem de soyut sınıflar sabitler tanımlayabilir.


  • Yapıcı Metotlar (Constructors): Soyut sınıflar yapıcı metotlara sahip olabilir. Arayüzler ise PHP 8.1 öncesinde yapıcı metot tanımlayamazdı. PHP 8.1 ve sonrası için arayüzler de yapıcı metot tanımlayabilir, ancak bu metotlar yine soyut olmak zorundadır.


  • Soyut Metotların Uygulanması: Bir soyut sınıfı miras alan veya bir arayüzü uygulayan somut sınıf, tüm soyut metotları veya arayüz metotlarını uygulamak zorundadır. Aksi takdirde, bu alt sınıfın da soyut olarak tanımlanması gerekir.


  • Kullanım Seçimi: Eğer sadece bir davranış sözleşmesi tanımlamak ve sınıflar arasında hiçbir ortak kod paylaşımı yoksa arayüz kullanın. Eğer sınıflar arasında ortak kod ve özellikler paylaşılıyorsa ve bu sınıfların aynı "tip" olduğunu belirtmek istiyorsanız soyut sınıf kullanın. Her ikisi de gerektiğinde birlikte kullanılabilir.


Yayınlanma Tarihi: 2025-10-18 05:00:36
Python Dilinde For Döngülerinin Etkin Kullanımı
Önceki Haber

Python Dilinde For Döngülerinin Etkin Kullanımı

Python Makaleleri
Sonraki Haber

JavaScript’te Temel Programlama: Sözdizimi ve Kullanım

JavaScript Makaleleri
JavaScript’te Temel Programlama: Sözdizimi ve Kullanım

Yorum yap

Yorum yapabilmek için  giriş  yapmalısınız.

Yorumlar

Bu yazı hakkında henüz yorum yapılmamıştır.
× PHP Dilinde Operatörler Kullanımı
Bu ilginizi çekebilir

PHP Dilinde Operatörler Kullanımı

PHP, programlama dillerinin temel yapı taşlarından biri olan operatörler aracılığıyla...