Menu
Coddy logo textTech

Metot Geçersiz Kılma

Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 51 / 104.

Metot geçersiz kılma (Method overriding), türetilmiş bir sınıfın, temel sınıfta zaten mevcut olan bir metodun kendi uygulamasını sağlamasıyla gerçekleşir. Bu, türetilmiş sınıfların aynı metot imzasını korurken kalıtımla alınan davranışı özelleştirmesine olanak tanır.

Bir metodu geçersiz kılmak (override etmek) için, türetilmiş sınıfta tam olarak aynı isim, dönüş türü ve parametrelerle bir metot tanımlamanız yeterlidir:

class Animal {
public:
    void speak() {
        std::cout << "Some sound" << std::endl;
    }
};

class Dog : public Animal {
public:
    void speak() {
        std::cout << "Woof!" << std::endl;
    }
};

Dog d;
d.speak();  // Çıktı: Woof!

Türetilmiş sınıf versiyonu temel sınıf versiyonunu gizler. Ancak, kapsam çözünürlük operatörünü kullanarak temel sınıf metoduna hala erişebilirsiniz:

class Dog : public Animal {
public:
    void speak() {
        Animal::speak();  // Temel sınıf versiyonunu çağır
        std::cout << "Woof!" << std::endl;
    }
};

Bu temel geçersiz kılma (overriding) biçiminde önemli bir sınırlama vardır. Türetilmiş bir nesneye bir temel sınıf işaretçisi veya referansı aracılığıyla eriştiğinizde, bunun yerine temel sınıf sürümü çağrılır:

Dog d;
Animal* ptr = &d;
ptr->speak();  // Çıktı: Some sound (not Woof!)

Bu durum, derleyicinin hangi metodun çağrılacağını gerçek nesne türüne göre değil, işaretçi türüne göre belirlemesi nedeniyle gerçekleşir. Doğru metodun gerçek nesneye dayalı olarak çağrıldığı gerçek çalışma zamanı polimorfizmini elde etmek için, bir sonraki derste ele alacağımız sanal fonksiyonlara ihtiyacınız olacak.

challenge icon

Görev

Kolay

Metot geçersiz kılma (method overriding) işlemini uygulamalı olarak gösteren bir bildirim sistemi oluşturalım. Bir temel Notifier sınıfı ve mesajların nasıl iletileceğini özelleştiren iki uzmanlaşmış bildirimci oluşturacaksınız.

Kodunuzu üç dosya halinde düzenleyeceksiniz:

  • Notifier.h: Aşağıdaki özelliklere sahip bir temel Notifier sınıfı tanımlayın:
    • Bir korumalı (protected) std::string recipient üyesi
    • Bir alıcı adı alan ve bunu saklayan bir yapıcı (constructor)
    • Şunu yazdıran bir genel (public) send(const std::string& message) metodu: Sending to <recipient>: <message>
  • EmailNotifier.h: Notifier sınıfından genel (public) olarak türetilen bir EmailNotifier sınıfı tanımlayın:
    • Bir alıcı alan ve bunu temel sınıfa ileten bir yapıcı
    • send() metodunu, önce Notifier::send() kullanarak temel sınıf versiyonunu çağıracak, ardından şunu yazdıracak şekilde geçersiz kılın: [Email sent successfully]
  • main.cpp: İki girdi okuyun (her biri ayrı bir satırda):
    1. Alıcı adı (string)
    2. Mesaj içeriği (string)

    Doğrudan main.cpp içinde, Notifier sınıfından genel (public) olarak türetilen bir SMSNotifier sınıfı tanımlayın:

    • Bir alıcı alan ve bunu temel sınıfa ileten bir yapıcı
    • send() metodunu şunu yazdıracak şekilde geçersiz kılın: SMS to <recipient>: <message> (temel sınıf davranışını çağırmadan tamamen değiştirerek)

    Aynı alıcıyı kullanarak her bildirimci türünden (temel Notifier, EmailNotifier ve SMSNotifier) birer nesne oluşturun. Her biri üzerinde girdi mesajıyla send() metodunu çağırın ve aralarına bir ayırıcı satır yazdırın:

    --- Base Notifier ---
    <output>
    --- Email Notifier ---
    <output>
    --- SMS Notifier ---
    <output>

Örneğin, Alice ve Hello there! girdileriyle:

--- Base Notifier ---
Sending to Alice: Hello there!
--- Email Notifier ---
Sending to Alice: Hello there!
[Email sent successfully]
--- SMS Notifier ---
SMS to Alice: Hello there!

EmailNotifier sınıfının önce üst metodu çağırarak temel davranışı nasıl genişlettiğine, SMSNotifier sınıfının ise bunu kendi uygulamasıyla nasıl tamamen değiştirdiğine dikkat edin. Başlık korumalarını (header guards) ve her dosyaya uygun başlıkları (headers) eklemeyi unutmayın.

Kopya kağıdı

Metot geçersiz kılma (method overriding), türetilmiş bir sınıfın, temel sınıftaki bir metodun kendi uygulamasını sağlamasına olanak tanır ve aynı metot imzasını (ad, dönüş türü ve parametreler) korur.

Temel geçersiz kılma sözdizimi:

class Animal {
public:
    void speak() {
        std::cout << "Some sound" << std::endl;
    }
};

class Dog : public Animal {
public:
    void speak() {
        std::cout << "Woof!" << std::endl;
    }
};

Dog d;
d.speak();  // Çıktı: Woof!

Türetilmiş sınıf metodu, temel sınıf versiyonunu gizler. Türetilmiş sınıftan temel sınıf metodunu çağırmak için kapsam çözünürlük operatörünü (scope resolution operator) kullanın:

class Dog : public Animal {
public:
    void speak() {
        Animal::speak();  // Temel sınıf versiyonunu çağır
        std::cout << "Woof!" << std::endl;
    }
};

Önemli kısıtlama: Türetilmiş bir nesneye bir temel sınıf işaretçisi (pointer) veya referansı aracılığıyla erişildiğinde, temel sınıf versiyonu çağrılır:

Dog d;
Animal* ptr = &d;
ptr->speak();  // Çıktı: Some sound (Woof! değil)

Bunun nedeni, derleyicinin hangi metodun çağrılacağını gerçek nesne türüne göre değil, işaretçi türüne göre belirlemesidir. Gerçek çalışma zamanı polimorfizmi (runtime polymorphism) için sanal fonksiyonları (virtual functions) kullanın.

Kendin dene

#include <iostream>
#include <string>
#include "Notifier.h"
#include "EmailNotifier.h"

using namespace std;

// TODO: Burada Notifier sınıfından genel (public) olarak miras alan SMSNotifier sınıfını tanımlayın
// - Alıcıyı (recipient) temel sınıfa (base class) ileten kurucu metot (constructor)
// - Şunu yazdırmak için send() metodunu geçersiz kılın (override): SMS to <recipient>: <message>
//   (temel davranışı tamamen değiştirin, üst sınıfın send() metodunu çağırmayın)

int main() {
    string recipient;
    string message;
    
    getline(cin, recipient);
    getline(cin, message);
    
    // TODO: recipient ile Notifier nesnesi oluşturun
    // "--- Base Notifier ---" yazdırın
    // message ile send() metodunu çağırın
    
    // TODO: recipient ile EmailNotifier nesnesi oluşturun
    // "--- Email Notifier ---" yazdırın
    // message ile send() metodunu çağırın
    
    // TODO: recipient ile SMSNotifier nesnesi oluşturun
    // "--- SMS Notifier ---" yazdırın
    // message ile send() metodunu çağırın
    
    return 0;
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler