- Konu sahibi
- #1
PHP’de
Bir sınıfın başına
Abstract sınıfın içinde normal metotlar da bulunabilir. Alt sınıf bu metotları doğrudan kullanabilir veya gerekirse geçersiz kılabilir. Abstract sınıf başka bir abstract sınıftan türetilebilir; ancak somut olarak kullanılacak en alt sınıf, miras aldığı ve henüz uygulanmamış tüm abstract metotları tamamlamalıdır.
Aşağıdaki PHP CLI örneği bildirim metnini yalnız ekrana yazar; gerçek e-posta veya SMS göndermez. dosya.php adıyla kaydedip uygun PHP ortamında php dosya.php ile çalıştırılabilir:
Bu kod bir PHP dosyasında çalıştırıldığında beklenen çıktı şuna benzer:
Burada
Abstract metodun kapsamı da alt sınıfta uyumlu olmalıdır. Örneğin üst sınıf metodu
Karar verirken temel ayrım şudur: Abstract sınıf, ortak uygulama kodu ve ortak durum taşımak için uygundur. Interface ise sınıfların hangi metotları sunacağını belirtir; genellikle ortak iş akışını paylaşmak yerine bir yetenek veya sözleşme tanımlar. PHP’de bir sınıf yalnızca bir sınıftan kalıtım alabilir, ancak birden fazla interface uygulayabilir.
Abstract sınıfı, alt sınıflar arasında gerçekten ortak olan bir temel bulunduğunda kullanın. Sadece birkaç sınıfın aynı metodu sunmasını istiyor, fakat ortak durum veya hazır davranış paylaşmıyorsanız interface daha esnek olabilir.
Sonraki adım olarak, ortak akışı üst sınıfa; değişen ayrıntıları abstract metotlara ayırın. Alt sınıfları mümkünse üst sınıf türüyle kullanan kod yazın. Böylece çağıran kod, belirli bir alt sınıfa gereksiz yere bağlanmadan yeni uygulamalar ekleyebilir.
abstract class, tek başına örneği oluşturulamayan ve alt sınıflara ortak özellik veya davranış aktarmak için kullanılan sınıftır. Abstract sınıf, hem normal metot ve özellikler içerebilir hem de alt sınıfların mutlaka uygulaması gereken abstract metotlar tanımlayabilir. Bu yapı, ortak kodu merkezileştirirken alt sınıflara belirli bir sözleşme uygular.Nasıl çalışır?
Bir sınıfın başına
abstract yazıldığında doğrudan new ile örneklenemez. Abstract metot ise yalnızca bildirimi içerir; metot gövdesi bulunmaz. Bu metodu tanımlayan her somut alt sınıf, PHP kalıtım kurallarına uyumlu metot imzasını kullanarak kendi uygulamasını yazmalıdır.Abstract sınıfın içinde normal metotlar da bulunabilir. Alt sınıf bu metotları doğrudan kullanabilir veya gerekirse geçersiz kılabilir. Abstract sınıf başka bir abstract sınıftan türetilebilir; ancak somut olarak kullanılacak en alt sınıf, miras aldığı ve henüz uygulanmamış tüm abstract metotları tamamlamalıdır.
Çalıştırılabilir tam örnek
Aşağıdaki PHP CLI örneği bildirim metnini yalnız ekrana yazar; gerçek e-posta veya SMS göndermez. dosya.php adıyla kaydedip uygun PHP ortamında php dosya.php ile çalıştırılabilir:
PHP:
<?php
abstract class Notification
{
public function send(string $message): void
{
echo $this->format($message) . PHP_EOL;
}
abstract protected function format(string $message): string;
}
final class EmailNotification extends Notification
{
protected function format(string $message): string
{
return 'E-posta: ' . $message;
}
}
final class SmsNotification extends Notification
{
protected function format(string $message): string
{
return 'SMS: ' . $message;
}
}
$email = new EmailNotification();
$email->send('Hesabınız hazır.');
$sms = new SmsNotification();
$sms->send('Doğrulama kodunuz gönderildi.');
Bu kod bir PHP dosyasında çalıştırıldığında beklenen çıktı şuna benzer:
Kod:
E-posta: Hesabınız hazır.
SMS: Doğrulama kodunuz gönderildi.
Burada
Notification sınıfından nesne üretilemez; çünkü sınıf abstract olarak tanımlanmıştır. Buna karşılık EmailNotification ve SmsNotification somut sınıflardır. Ortak send() akışı üst sınıfta tutulur, kanalın kendine özgü biçimlendirmesi ise format() içinde alt sınıfa bırakılır.Abstract metodun kapsamı da alt sınıfta uyumlu olmalıdır. Örneğin üst sınıf metodu
protected ise alt sınıf onu daha dar bir görünürlükle private yapamaz. Parametreler, dönüş tipi ve gerekli uyumluluk kuralları da korunmalıdır.Abstract class mı, interface mi?
Karar verirken temel ayrım şudur: Abstract sınıf, ortak uygulama kodu ve ortak durum taşımak için uygundur. Interface ise sınıfların hangi metotları sunacağını belirtir; genellikle ortak iş akışını paylaşmak yerine bir yetenek veya sözleşme tanımlar. PHP’de bir sınıf yalnızca bir sınıftan kalıtım alabilir, ancak birden fazla interface uygulayabilir.
| İhtiyaç | Uygun tercih | Nedeni |
|---|---|---|
| Ortak metot gövdesi ve ortak özellikler | Abstract class | Hazır davranış alt sınıflara aktarılır. |
| Birden fazla bağımsız sınıfa aynı yeteneği zorunlu kılmak | Interface | Sınıflar farklı hiyerarşilerden gelirken aynı sözleşmeyi uygulayabilir. |
| Yalnızca ortak yardımcı kod | Normal sınıf veya ayrı servis | Gereksiz kalıtım bağımlılığı oluşturulmaz. |
Abstract sınıfı, alt sınıflar arasında gerçekten ortak olan bir temel bulunduğunda kullanın. Sadece birkaç sınıfın aynı metodu sunmasını istiyor, fakat ortak durum veya hazır davranış paylaşmıyorsanız interface daha esnek olabilir.
Sık yapılan hatalar ve doğru kararlar
- Abstract sınıftan doğrudan nesne üretmeye çalışmayın.
new Notification()kullanımı hata verir; somut bir alt sınıf oluşturup onu örnekleyin. - Abstract metodu alt sınıfta eksik bırakmayın. Somut sınıfın bildirimi uygulanmamış abstract metot bırakıyorsa PHP hata verir; sorun yalnız nesne üretme anına ertelenmiş değildir.
- Alt sınıfın metodunu daha dar görünür yapmayın. Üst sınıftaki
publicmetotprotectedveyaprivateyapılamaz. - Abstract sınıfa her ortak kodu doldurmayın. Alt sınıflar arasında paylaşılmayan davranışları ayrı bir sınıfa veya servise taşımak bağımlılığı azaltır.
- Sadece değişken davranış için abstract sınıf seçmeyin. Birden fazla sınıf hiyerarşisinde kullanılacak bir sözleşme gerekiyorsa interface seçeneğini de değerlendirin.
Sonraki adım olarak, ortak akışı üst sınıfa; değişen ayrıntıları abstract metotlara ayırın. Alt sınıfları mümkünse üst sınıf türüyle kullanan kod yazın. Böylece çağıran kod, belirli bir alt sınıfa gereksiz yere bağlanmadan yeni uygulamalar ekleyebilir.