--- id: csharp-polymorphism title: "C# Polymorphism" category: "Programming_Language" status: "draft" verification_status: "conceptual" canonical_id: "" aliases: ["virtual override C#", "method overriding C#", "C# ๋‹คํ˜•์„ฑ"] duplicate_of: "" source_trust_level: "B" confidence_score: 0.85 created_at: 2026-07-04 updated_at: 2026-07-04 review_reason: "" merge_history: [] tags: ["csharp", "programming-language", "w3schools", "oop", "polymorphism"] raw_sources: ["https://www.w3schools.com/cs/cs_polymorphism.php"] applied_in: [] github_commit: "" --- # [[CSharp Polymorphism]] ## ๐ŸŽฏ ํ•œ ์ค„ ํ†ต์ฐฐ (One-line insight) C# requires the EXACT same two-keyword pairing already confirmed for modern C++ in Topic_CPP โ€” `virtual` on the base class method, `override` on each derived class's replacement โ€” and this chapter goes further than the CPP chapter did by explicitly demonstrating the FAILURE case first: without `virtual`/`override`, calling `animalSound()` through an `Animal`-typed reference to a `Pig`/`Dog` object prints the BASE class's message every time, because (per the tutorial's own explanation) same-named methods without these keywords simply aren't polymorphic at all โ€” they're just separately-named methods that happen to share an identifier. [S1] ## ๐Ÿง  ํ•ต์‹ฌ ๊ฐœ๋… (Core concepts) - **Polymorphism ("many forms")** โ€” occurs among classes related by inheritance; lets a single action be performed in different ways depending on the actual object type. [S1] - **Without `virtual`/`override`** โ€” same-named methods in base and derived classes do NOT achieve polymorphism; calling the method through a base-typed reference always runs the BASE class's version, regardless of the actual object's derived type. [S1] - **`virtual` keyword** โ€” placed on the BASE class method to allow it to be overridden. [S1] - **`override` keyword** โ€” placed on each DERIVED class's replacement method, required alongside base `virtual` to achieve true polymorphic dispatch. [S1] - **Base-typed reference, derived object** โ€” `Animal myPig = new Pig();` โ€” the variable's declared TYPE is the base class, but the actual OBJECT is the derived class; with `virtual`/`override`, the call resolves to the derived class's implementation at runtime. [S1] ## ๐Ÿ“– ์„ธ๋ถ€ ๋‚ด์šฉ (Details) - Without virtual/override (the "not the output I was looking for" case): base and derived `Animal`/`Pig`/`Dog` each define their own `animalSound()`, but `Animal myPig = new Pig(); myPig.animalSound();` prints `"The animal makes a sound"` for ALL three objects, not the derived versions. [S1] - With virtual/override: `public virtual void animalSound()` in `Animal`, `public override void animalSound()` in `Pig` and `Dog` โ†’ `myAnimal.animalSound()` prints `"The animal makes a sound"`, `myPig.animalSound()` prints `"The pig says: wee wee"`, `myDog.animalSound()` prints `"The dog says: bow wow"` โ€” each resolves to its OWN class's implementation. [S1] ## โš–๏ธ ๋ชจ์ˆœ ๋ฐ ์—…๋ฐ์ดํŠธ (Contradictions & updates) - **virtual/override ํŽ˜์–ด๋ง์ด C++์™€ ์™„์ „ํžˆ ๋™์ผ**: ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์— virtual, ํŒŒ์ƒ ํด๋ž˜์Šค์— override๋ฅผ ๋ถ™์—ฌ์•ผ ๋‹คํ˜•์„ฑ์ด ์ž‘๋™ํ•œ๋‹ค๋Š” ๊ทœ์น™์ด Topic_CPP์˜ Virtual Functions ์ฑ•ํ„ฐ(C++11์˜ override ํ‚ค์›Œ๋“œ ํฌํ•จ)์™€ ์ฐจ์ด๊ฐ€ ์—†๋‹ค๋Š” ์ ์ด ํ™•์ธ๋จ. [S1] - **์‹คํŒจ ์‚ฌ๋ก€๋ฅผ ๋จผ์ € ๋ณด์—ฌ์คŒ์œผ๋กœ์จ virtual์˜ ํ•„์š”์„ฑ์„ ๋ช…ํ™•ํžˆ ํ•จ**: Topic_CPP์˜ Virtual Functions ์ฑ•ํ„ฐ์™€ ๋‹ฌ๋ฆฌ, ์ด๋ฒˆ ์ฑ•ํ„ฐ๋Š” virtual/override ์—†์ด ๋จผ์ € ์‹คํ–‰ํ•ด "๊ธฐ๋Œ€์™€ ๋‹ค๋ฅธ ์ถœ๋ ฅ"์ด ๋‚˜์˜ค๋Š” ๊ฒƒ์„ ๋ณด์—ฌ์ค€ ๋’ค์—์•ผ virtual/override๋ฅผ ๋„์ž…ํ•œ๋‹ค๋Š” ์ ์ด ๊ต์œก์  ๊ตฌ์„ฑ์˜ ์ฐจ์ด๋กœ ํ™•์ธ๋จ. [S1] ## ๐Ÿ› ๏ธ ์ ์šฉ ์‚ฌ๋ก€ (Applied in summary) Animal ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์™€ Pig/Dog ํŒŒ์ƒ ํด๋ž˜์Šค๊ฐ€ ๊ฐ๊ฐ ๋‹ค๋ฅธ animalSound()๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ , virtual/override ์—†์ด๋Š” ๋ชจ๋‘ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค ๋ฉ”์‹œ์ง€๋งŒ ์ถœ๋ ฅ๋˜๋‹ค๊ฐ€ virtual/override๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๊ฐ ๋™๋ฌผ ๊ณ ์œ ์˜ ์†Œ๋ฆฌ๊ฐ€ ์ถœ๋ ฅ๋˜๋Š” before/after ๋น„๊ต๊ฐ€ ์›๋ฌธ์—์„œ ์ง์ ‘ ์‹ค์ „ ํ™œ์šฉ ์‚ฌ๋ก€๋กœ ์ œ์‹œ๋จ. [S1] ## ๐Ÿ’ป ์ฝ”๋“œ ํŒจํ„ด (Code patterns) Without vs. with virtual/override โ€” same call site, different resolved method (C#): ```csharp // Without virtual/override -- always prints base class message class Animal { public void animalSound() { Console.WriteLine("The animal makes a sound"); } } class Pig : Animal { public void animalSound() { Console.WriteLine("The pig says: wee wee"); } } Animal myPig1 = new Pig(); myPig1.animalSound(); // "The animal makes a sound" -- NOT polymorphic // With virtual/override -- resolves to the actual object's type class Animal2 { public virtual void animalSound() { Console.WriteLine("The animal makes a sound"); } } class Pig2 : Animal2 { public override void animalSound() { Console.WriteLine("The pig says: wee wee"); } } Animal2 myPig2 = new Pig2(); myPig2.animalSound(); // "The pig says: wee wee" -- polymorphic ``` ## โœ… ๊ฒ€์ฆ ์ƒํƒœ ๋ฐ ์‹ ๋ขฐ๋„ - **์ƒํƒœ:** draft - **๊ฒ€์ฆ ๋‹จ๊ณ„:** conceptual - **์ถœ์ฒ˜ ์‹ ๋ขฐ๋„:** B (W3Schools โ€” widely used educational reference, not a primary standards body) - **์‹ ๋ขฐ ์ ์ˆ˜:** 0.85 - **์ค‘๋ณต ๊ฒ€์‚ฌ ๊ฒฐ๊ณผ:** ์‹ ๊ทœ ์ƒ์„ฑ (New discovery) ## ๐Ÿ”— ์ง€์‹ ๊ทธ๋ž˜ํ”„ (Knowledge Graph) - **์ƒ์œ„/๋ฃจํŠธ:** [[C# Tutorial]] - **๊ด€๋ จ ๊ฐœ๋…:** [[CSharp Inheritance]], [[CSharp Abstract]], [[CPP Virtual Functions]], [[CPP Polymorphism]] - **์ฐธ์กฐ ๋งฅ๋ฝ:** Polymorphism & Abstract ์„น์…˜ โ€” Abstraction ์ฑ•ํ„ฐ๋กœ ์ด์–ด์ง. ## ๐Ÿ“š ์ถœ์ฒ˜ (Sources) - [S1] W3Schools โ€” C# Polymorphism โ€” https://www.w3schools.com/cs/cs_polymorphism.php ## ๐Ÿ“ ๋ณ€๊ฒฝ ์ด๋ ฅ (Change history) - 2026-07-04: Initial draft synthesized from the W3Schools "C# Polymorphism" page (Astra wiki-curation, P-Reinforce v3.1 format).