İçeriğe atla

Çokbiçimlilik

Vikipedi, özgür ansiklopedi

Çokbiçimlilik (İngilizcepolymorphism), bir türün bir başka tür gibi davranabilme ve bu tür gibi kullanılabilme özelliğidir. Nesne yönelimli programlama dillerinde çokbiçimlilik özelliği ise aynı temel sınıftan türetilmiş olan sınıflarda paylaşılan, başka bir ifadeyle aşırı yüklenen aynı metodun bu sınıflarda farklı şekillerde uyarlanabilmesidir. Nesnenin davranışı çalışma anında belirlendiği için programcılar, çokbiçimlilik özelliği sayesinde nesnelerin türünü önceden bilmek zorunda kalmaz.

#include <string>
#include <type_traits>
#include <iostream>

struct Animal {
  virtual ~Animal() = default;

  virtual std::string talk() const = 0;
};

struct Cat : public Animal {
  std::string talk() const override { return "Miyav!"; }
};

struct Dog : public Animal {
  std::string talk() const override { return "Hav! Hav!"; }
};

static_assert(std::is_polymorphic_v<Animal>);
static_assert(std::is_base_of_v<Animal, Cat>);
static_assert(std::is_base_of_v<Animal, Dog>);

std::string talk(const Animal& a) {
  return a.talk();
}

int main() {
  Cat minnos;
  Dog karabas;

  std::cout << talk(minnos) << '\n';  // Miyav!
  std::cout << talk(karabas) << '\n'; // Hav! Hav!
}
// C++17 ve sonrasi std::variant tipi kullanarak
// https://en.cppreference.com/w/cpp/utility/variant
#include <string>
#include <variant>
#include <iostream>

struct Cat {
  std::string talk() const { return "Miyav!"; }
};

struct Dog {
  std::string talk() const { return "Hav! Hav!"; }
};

using Animal = std::variant<Cat, Dog>;

std::string talk(const Animal& a) {
  struct v {
    std::string operator()(const Cat& c) const { return c.talk(); }
    std::string operator()(const Dog& d) const { return d.talk(); }
  };

  return std::visit(v{}, a);
}

int main() {
  Cat minnos;
  Dog karabas;

  std::cout << talk(minnos) << '\n';  // Miyav!
  std::cout << talk(karabas) << '\n'; // Hav! Hav!
}
// C++17 ve sonrasi std::any tipi kullanarak:
// https://en.cppreference.com/w/cpp/utility/any
#include <string>
#include <any>
#include <iostream>

struct Cat {
  std::string talk() const { return "Miyav!"; }
};

struct Dog {
  std::string talk() const { return "Hav! Hav!"; }
};

std::string talk(const std::any &animal) {
  if (const Cat *c = std::any_cast<Cat>(&animal))
    return c->talk();

  else if (const Dog *d = std::any_cast<Dog>(&animal))
    return d->talk();

  return std::string{};
}

int main() {
  Cat minnos;
  Dog karabas;

  std::cout << talk(minnos) << '\n';  // Miyav!
  std::cout << talk(karabas) << '\n'; // Hav! Hav!
}
// C++20 auto fonksiyon parametresi kullanarak
#include <string>
#include <iostream>

struct Cat {
  std::string talk() const { return "Miyav!"; }
};

struct Dog {
  std::string talk() const { return "Hav! Hav!"; }
};

std::string talk(const auto &animal) {
  return animal.talk();
}

int main() {
  Cat minnos;
  Dog karabas;

  std::cout << talk(minnos) << '\n';  // Miyav!
  std::cout << talk(karabas) << '\n'; // Hav! Hav!
}
// C++20 concept ile türü belli üye fonksiyona sahip olacak şekilde kısıtlayarak
// https://en.cppreference.com/w/cpp/language/constraints
#include <string>
#include <iostream>
#include <concepts>

template <typename T>
concept Talkable = requires(T t) {
  { t.talk() } -> std::same_as<std::string>;
};

struct Cat {
  std::string talk() const { return "Miyav!"; }
};

struct Dog {
  std::string talk() const { return "Hav! Hav!"; }
};

std::string talk(const Talkable auto &animal) {
  return animal.talk();
}

int main() {
  Cat minnos;
  Dog karabas;

  std::cout << talk(minnos) << '\n';  // Miyav!
  std::cout << talk(karabas) << '\n'; // Hav! Hav!
}
interface IAnimal {
  String talk();
}

class Cat implements IAnimal {
  public String talk() { return "Miyav!"; }
}

class Dog implements IAnimal {
  public String talk() { return "Hav! Hav!"; }
}

public class Test {
  public static void main(String[] args) {
    IAnimal cat = new Cat();
    IAnimal dog = new Dog();

    System.out.println(cat.talk()); // Miyav!
    System.out.println(dog.talk()); // Hav! Hav!
  }
}