ตัวอย่าง OOP ในแต่ละภาษา

OOP 101 : ตัวอย่าง OOP ในแต่ละภาษา

แนวคิด OOP (Object-Oriented Programming) มีหลักการ 4 อย่างหลัก ๆ

  • Encapsulation (การห่อหุ้มข้อมูล)
  • Inheritance (การสืบทอดคุณสมบัติ)
  • Polymorphism (พ้องรูป) ความสามารถในการใช้ชื่อ method เดียวกันในหลายรูปแบบ
  • Abstraction (นามธรรม) การซ่อนความซับซ้อน และเปิดเผยเฉพาะสิ่งที่จำเป็น คือ รู้แค่ว่ามันทำได้ แต่ไม่ต้องรู้ว่าทำอย่างไร

ต่อไปนี้คือตัวอย่างโค้ด OOP พื้นฐานในหลายภาษา

1. Java

				
					abstract class Animal {
    protected String name;
    public Animal(String name) {
        this.name = name;
    }
    public abstract String speak();
}

class Dog extends Animal {
    public Dog(String name) { super(name); }
    public String speak() { return name + " says Woof!"; }
}

class Cat extends Animal {
    public Cat(String name) { super(name); }
    public String speak() { return name + " says Meow!"; }
}

public class Main {
    public static void main(String[] args) {
        Animal[] animals = { new Dog("Buddy"), new Cat("Milo") };
        for (Animal a : animals) {
            System.out.println(a.speak());
        }
    }
}

				
			

2. JavaScript

				
					class Animal {
    constructor(name) {
        this._name = name;
        if (new.target === Animal) throw new Error("Abstract class");
    }
    speak() {
        throw new Error("Must override");
    }
}

class Dog extends Animal {
    speak() { return `${this._name} says Woof!`; }
}

class Cat extends Animal {
    speak() { return `${this._name} says Meow!`; }
}

function main() {
    const animals = [new Dog("Buddy"), new Cat("Milo")];
    animals.forEach(a => console.log(a.speak()));
}

main();

				
			

3. TypeScript

				
					abstract class Animal {
    protected name: string;
    constructor(name: string) { this.name = name; }
    abstract speak(): string;
}

class Dog extends Animal {
    speak(): string { return `${this.name} says Woof!`; }
}

class Cat extends Animal {
    speak(): string { return `${this.name} says Meow!`; }
}

function main() {
    const animals: Animal[] = [new Dog("Buddy"), new Cat("Milo")];
    animals.forEach(a => console.log(a.speak()));
}

main();

				
			

4. Python

				
					from abc import ABC, abstractmethod

class Animal(ABC):
    def __init__(self, name):
        self._name = name  # Encapsulation

    @abstractmethod
    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        return f"{self._name} says Woof!"

class Cat(Animal):
    def speak(self):
        return f"{self._name} says Meow!"

def main():
    animals = [Dog("Buddy"), Cat("Milo")]
    for a in animals:
        print(a.speak())

if __name__ == "__main__":
    main()

				
			

5. C#

				
					abstract class Animal {
    protected string name;
    public Animal(string name) { this.name = name; }
    public abstract string Speak();
}

class Dog : Animal {
    public Dog(string name) : base(name) { }
    public override string Speak() => $"{name} says Woof!";
}

class Cat : Animal {
    public Cat(string name) : base(name) { }
    public override string Speak() => $"{name} says Meow!";
}

class Program {
    static void Main() {
        var animals = new List<Animal> { new Dog("Buddy"), new Cat("Milo") };
        animals.ForEach(a => Console.WriteLine(a.Speak()));
    }
}

				
			

6. C++

				
					class Animal {
protected:
    string name;
public:
    Animal(string name): name(name) {}
    virtual string speak() = 0;
};

class Dog : public Animal {
public:
    Dog(string name): Animal(name) {}
    string speak() override { return name + " says Woof!"; }
};

class Cat : public Animal {
public:
    Cat(string name): Animal(name) {}
    string speak() override { return name + " says Meow!"; }
};

int main() {
    vector<Animal*> animals = { new Dog("Buddy"), new Cat("Milo") };
    for (auto a : animals) {
        cout << a->speak() << endl;
        delete a;
    }
}

				
			

7. Kotlin

				
					abstract class Animal(protected val name: String) {
    abstract fun speak(): String
}

class Dog(name: String) : Animal(name) {
    override fun speak() = "$name says Woof!"
}

class Cat(name: String) : Animal(name) {
    override fun speak() = "$name says Meow!"
}

fun main() {
    val animals = listOf(Dog("Buddy"), Cat("Milo"))
    animals.forEach { println(it.speak()) }
}
				
			

8. Ruby

				
					class Animal
  def initialize(name)
    @name = name
  end
  def speak
    raise NotImplementedError
  end
end

class Dog < Animal
  def speak
    "#{@name} says Woof!"
  end
end

class Cat < Animal
  def speak
    "#{@name} says Meow!"
  end
end

def main
  animals = [Dog.new("Buddy"), Cat.new("Milo")]
  animals.each { |a| puts a.speak }
end

main

				
			

9. PHP

				
					<?php
abstract class Animal {
    protected $name;
    public function __construct($name) {
        $this->name = $name;
    }
    abstract public function speak();
}

class Dog extends Animal {
    public function speak() {
        return "{$this->name} says Woof!";
    }
}

class Cat extends Animal {
    public function speak() {
        return "{$this->name} says Meow!";
    }
}

function main() {
    $animals = [new Dog("Buddy"), new Cat("Milo")];
    foreach ($animals as $animal) {
        echo $animal->speak() . "\\n";
    }
}
main();
?>

				
			

10. Dart

				
					abstract class Animal {
  final String _name;
  Animal(this._name);
  String speak();
}

class Dog extends Animal {
  Dog(String name) : super(name);
  @override
  String speak() => '$_name says Woof!';
}

class Cat extends Animal {
  Cat(String name) : super(name);
  @override
  String speak() => '$_name says Meow!';
}

void main() {
  final animals = [Dog("Buddy"), Cat("Milo")];
  for (final a in animals) {
    print(a.speak());
  }
}

				
			

11. Swift

				
					class Animal {
    private var name: String
    init(name: String) {
        self.name = name
    }
    func speak() -> String {
        fatalError("Abstract method must be overridden")
    }
}

class Dog: Animal {
    override func speak() -> String {
        return "\(name) says Woof!"
    }
}

class Cat: Animal {
    override func speak() -> String {
        return "\(name) says Meow!"
    }
}

func main() {
    let animals: [Animal] = [Dog(name: "Buddy"), Cat(name: "Milo")]
    for animal in animals {
        print(animal.speak())
    }
}

main()

				
			

12. Rust (ใช้ Trait แทน Class แบบปกติ)

				
					trait Animal {
    fn speak(&self) -> String;
}

struct Dog { name: String }
struct Cat { name: String }

impl Animal for Dog {
    fn speak(&self) -> String {
        format!("{} says Woof!", self.name)
    }
}

impl Animal for Cat {
    fn speak(&self) -> String {
        format!("{} says Meow!", self.name)
    }
}

fn main() {
    let animals: Vec<Box<dyn Animal>> = vec![
        Box::new(Dog { name: "Buddy".to_string() }),
        Box::new(Cat { name: "Milo".to_string() })
    ];
    for animal in animals {
        println!("{}", animal.speak());
    }
}

				
			

13. Scala

				
					abstract class Animal(val name: String) {
  def speak(): String
}

class Dog(name: String) extends Animal(name) {
  def speak(): String = s"$name says Woof!"
}

class Cat(name: String) extends Animal(name) {
  def speak(): String = s"$name says Meow!"
}

object Main {
  def main(args: Array[String]): Unit = {
    val animals: List[Animal] = List(new Dog("Buddy"), new Cat("Milo"))
    animals.foreach(a => println(a.speak()))
  }
}

				
			

14. Go (ไม่มี class แต่ใช้ struct + interface ทำ OOP ได้)

				
					type Animal interface {
    Speak() string
}

type dog struct { name string }
func (d dog) Speak() string { return d.name + " says Woof!" }

type cat struct { name string }
func (c cat) Speak() string { return c.name + " says Meow!" }

func main() {
    animals := []Animal{dog{"Buddy"}, cat{"Milo"}}
    for _, a := range animals {
        fmt.Println(a.Speak())
    }
}