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, türetilmiş bir sınıfın temel sınıfta zaten bulunan bir metot için kendi uygulamasını sağlamasıyla gerçekleşir. Bu, türetilmiş sınıfların aynı metot imzasını korurken devralınan davranışı özelleştirmesine olanak tanır.

Bir yöntemi geçersiz kılmak için türetilmiş sınıfta aynı ada, dönüş türüne ve parametrelere sahip bir yöntem tanımlaman 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

Yöntem geçersiz kılmayı uygulamalı olarak gösteren bir bildirim sistemi oluşturalım. Bir temel Notifier sınıfı ve iletilerin nasıl gönderileceğini özelleştiren iki özel bildirim sınıfı oluşturacaksın.

Kodunu üç dosyaya ayıracaksın:

  • Notifier.h: Şunları içeren bir temel Notifier sınıfı tanımla:
    • Protected bir std::string recipient üyesi
    • Bir alıcı adı alan ve bunu kaydeden bir oluşturucu
    • Şunu yazdıran bir public send(const std::string& message) yöntemi: Sending to <recipient>: <message>
  • EmailNotifier.h: EmailNotifier sınıfından public olarak türeyen bir Notifier sınıfı tanımla:
    • Bir alıcı alan ve bunu temel sınıfa aktaran bir oluşturucu
    • Önce send() kullanarak temel sınıf sürümünü çağıran, ardından Notifier::send() yazdıran [Email sent successfully] yöntemini geçersiz kıl
  • main.cpp: İki girdi oku (her biri ayrı bir satırda):
    1. Alıcı adı (string)
    2. İleti içeriği (string)

    SMSNotifier sınıfından public olarak türeyen bir Notifier sınıfını doğrudan main.cpp içinde tanımla:

    • Bir alıcı alan ve bunu temel sınıfa aktaran bir oluşturucu
    • Temel davranışı çağırmadan tamamen değiştirecek şekilde şunu yazdıran send() yöntemini geçersiz kıl: SMS to <recipient>: <message>

    Aynı alıcıyı kullanarak her bildirim türünden (temel Notifier, EmailNotifier ve SMSNotifier) birer nesne oluştur. Girdi iletisiyle her biri üzerinde send() çağrısı yap ve her birinin arasına bir ayraç satırı yazdır:

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

Örneğin, girdiler Alice ve Hello there! olduğunda:

--- 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 sınıf yöntemini çağırarak temel davranışı nasıl genişlettiğine, SMSNotifier sınıfının ise bunu kendi uygulamasıyla tamamen değiştirdiğine dikkat et. Header guard'larını eklemeyi ve her dosyaya uygun başlık dosyalarını dahil etmeyi unutma.

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

Kendi başına pratik yap: Online C++ derleyicisi