เพิ่มมูลค่าสินค้า 2 เท่า! ด้วยเทคนิค ‘Spot UV & ปั๊มฟอยล์’ เปลี่ยนกล่องธรรมดาให้ดูแบรนด์เนม
“This is a common interview question that assesses your understanding of an object-oriented programming concept called **Polymorphism**.
Let’s break down the scenario and the explanation:
### The Scenario:
You have a `Dog` class and a `Cat` class, both of which inherit from an `Animal` class.
The `Animal` class has a virtual method `MakeSound()`.
Both `Dog` and `Cat` classes override this `MakeSound()` method to provide their specific sound.
“`csharp
public class Animal
{
public virtual void MakeSound()
{
Console.WriteLine(“Animal makes a sound.”);
}
}
public class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine(“Woof!”);
}
}
public class Cat : Animal
{
public override void MakeSound()
{
Console.WriteLine(“Meow!”);
}
}
“`
Now, consider this code snippet:
“`csharp
Animal myPet;
myPet = new Dog();
myPet.MakeSound(); // What is printed?
myPet = new Cat();
myPet.MakeSound(); // What is printed?
“`
### Explanation of What is Printed and Why:
1. `myPet = new Dog();`
`myPet.MakeSound();`
**Output: “Woof!”**
2. `myPet = new Cat();`
`myPet.MakeSound();`
**Output: “Meow!”**
**Why? This is due to Polymorphism.**
**Polymorphism** (meaning “many forms”) is one of the fundamental principles of object-oriented programming. In this context, it specifically refers to **runtime polymorphism** (also known as dynamic dispatch).
Here’s how it works:
* **Reference Type vs. Object Type:**
* `Animal myPet;` declares a variable `myPet` of type `Animal`. This is its **reference type**.
* `myPet = new Dog();` assigns an actual `Dog` object to `myPet`. This `Dog` object is the **object type** (or actual type).
* Crucially, a `Dog` *is an* `Animal` (inheritance principle), so this assignment is valid. The same applies to `Cat`.
* **Virtual Methods and Overriding:**
* By declaring `MakeSound()` as `virtual` in the `Animal` class, you’re signaling that derived classes *can* provide their own specific implementation of this method.
* The `override` keyword in `Dog` and `Cat` classes indicates that they are providing such a specific implementation.
* **Dynamic Dispatch:**
* When you call `myPet.MakeSound()`, the .NET runtime doesn’t just look at the `myPet` variable’s **reference type** (`Animal`).
* Instead, because `MakeSound()` is a virtual method, the runtime inspects the **actual type** of the object currently stored in `myPet` (which could be `Dog` or `Cat` at different times).
* It then executes the `MakeSound()` implementation *specific to that actual object type*.
So, when `myPet` holds a `Dog` object, `Dog`’s `MakeSound()` is called. When `myPet` holds a `Cat` object, `Cat`’s `MakeSound()` is called. This allows you to write code that interacts with a general `Animal` type, but still get the specific behavior of the derived types without needing to know their exact type at compile time or use cumbersome `if/else` or `switch` statements based on type casting.
### In Summary:
Polymorphism allows objects of different classes to be treated as objects of a common superclass. The actual method implementation invoked depends on the object’s **actual type** at runtime, not the reference type of the variable holding the object.”
