Saladpuk.com
🏆 เนื้อหาหลัก
🏆 เนื้อหาหลัก
  • 💖สลัดผัก
  • 📰มีอะไรใหม่บ้าง
    • 2020
      • 2020-11
      • 2020-10
      • 2020-09
      • 2020-08
      • 2020-03
      • 2020-02
      • 2020-01
    • 2019
      • 2019-12
      • 2019-11
      • 2019-10
      • 2019-09
      • 2019-08
  • 🤔อ่านเรื่องไรดี ?
  • มือใหม่หัดเขียนโค้ด
    • 👶เขียนโค้ดด้วยภาษา C#
      • เกิดมาไม่เคยเขียนโค้ดมาก่อนเบย
      • 👶พื้นฐาน
        • 1.โปรแกรมที่ต้องลง
        • 2.โครงสร้างของโค้ด
        • 3.ชนิดของข้อมูล
        • 4.การสร้างตัวแปร
        • 5.คำสั่งพื้นฐาน
        • 6.การแปลงข้อมูล
        • 7.การเปรียบเทียบค่า
        • 8.การตัดสินใจด้วย IF statements
        • 9.การตัดสินใจด้วย Switch statements
        • 10.การทำงานซ้ำๆด้วย While
        • 11.การทำงานซ้ำๆด้วย Do While
        • 12.การทำงานซ้ำๆด้วย For
        • 13.การแก้โจทย์จากรูป
        • 14.มารู้จักกับ Array กัน
      • 🧑ระดับกลาง
        • 15.Value type vs Reference type
        • 16.ลดงานซ้ำๆด้วย Method
        • 17.มารู้จักกับ Class & Field กัน
        • 18.มารู้จักกับ Constructor กันบ้าง
        • 19.มาเขียน Method ใน Class กัน
        • 20.มารู้จักกับ Property กัน
        • 21.ลองใช้คลาสแบบจริงจังบ้าง
        • 22.การสืบทอด Inheritance
        • 23.Polymorphism
        • 24.Abstract Class
        • 25.Interface
        • 26.Namespace
        • 27.Enum
        • 28.Exception handler
        • 29.ลงลึกกับ string
        • 30.StringBuilder เพื่อนคู่ string
      • 👨⏳ระดับสูง
        • Generic
        • Delegates
        • Action & Func
        • Lambda expression
        • LINQ
        • พระคัมภีร์การใช้คำสั่ง LINQ
      • 💡Tips
        • 💡C# version 8.0
        • 💡Boxing & Unboxing
    • 👶Algorithm
      • 👾Algorithm Big-O
      • 👽Algorithm P & NP
    • 👦OOP
      • 💖Abstraction
      • 💖Encapsulation
      • 🏆Abstraction & Encapsulation
      • 💖Inheritance
      • 💖Polymorphism
      • 🏆Inheritance & Polymorphism
      • 📝ลองเขียน OOP ดูดิ๊
      • 👑OOP + Power of Design
      • 🥰เทคนิคในการออกแบบ
    • 👶บทสรุปฐานข้อมูล
      • เก็บรูปในฐานข้อมูล
      • Database indexing
      • การลบข้อมูล
    • 👦Communication Patterns
    • 👦Design Patterns
      • 🤰Creational Patterns
        • 🏭Factory Method
        • 🏭Abstract Factory
        • ☝️ Singleton Pattern
        • 🏗️ Builder Pattern
        • 🎎Prototype Pattern
      • 🧱Structural Patterns
        • 🔌Adapter Pattern
        • 📪Proxy Pattern
  • Puzzle
    • 🧠Challenges
      • 🐴Google ม้า 25 ตัว
      • 🌉Amazon เสา 2 ต้น
      • 🥇ทองเก๊
      • 💊ยาต้านโควิด
      • 🎩CP หมวก 5 ใบ
      • 🧓Einstein's Riddle 01
  • พื้นฐานที่ควรต้องรู้
    • 🐳Docker
      • 📦Docker Containers
      • 🃏Docker Exercise 01
      • 🛠️ Docker Tools
      • 🗃️ Docker Registry
      • 🖼️ Container Image
      • 📢Docker Push
      • 🔄WSL
    • 👶Clean Code
      • 🧓Uncle Bob - Clean Code
      • 🧓Uncle Bob - Comments
      • 🧓Uncle Bob - Naming
      • 🧓Uncle Bob - Mindset
      • 🧓Uncle Bob - TDD
    • 👶Code Smells
    • 👶สิ่งที่คนเขียนโค้ดมักเข้าใจผิด
    • 👶AI พื้นฐาน
    • 👶Git พื้นฐาน
      • Git branching strategy
    • 👶Cloud พื้นฐาน
    • 👶UML พื้นฐาน
      • Activity Diagram
      • Class Diagram
      • Sequence Diagram
      • Use case Diagram
      • บทสรุปการใช้ UML
    • 👶Data Scientist
      • การเลือก Algorithms ให้ AI (1/5)
      • การเตรียมข้อมูลให้ AI (2/5)
      • หลักการตั้งคำถามให้ AI (3/5)
      • แฉความลับของ AI Model (4/5)
      • หัดเขียน AI จาก AI ของคนอื่น (5/5)
    • 👶DevOps พื้นฐาน
    • 👶Docker ขั้นพื้นฐาน
      • Image and Container
      • แชร์ Docker Image ที่สร้างไว้
    • 👶Microservices พื้นฐาน
      • Microservices ที่ดีมีลักษณะยังไง
      • Microservices Tips
      • จาก Monolith สู่ Microservices
    • 👶ความรู้พื้นฐานในการทำเว็บ
    • 👦Bottlenecks of Software
      • หัวใจที่สำคัญที่สุดของฐานข้อมูล
    • 👦Agile Methodology
      • Agile in a Nutshell
      • Software Development Life Cycle
      • Code Review
    • 👦Security พื้นฐาน
      • การเก็บรหัสผ่านที่ถูกต้อง
      • Security in actions
        • Hash function
      • Security Principles
      • 😎The Matrix 1
      • 😎The Matrix 2
      • HTTPS in a nutshell
    • 👦SOLID Design Principles
      • มารู้จักกับ SOLID กันดีกว่า
      • Single-Responsibility Principle
      • Open/Closed Principle
      • Liskov Substitution Principle
      • Interface Segregation Principle
      • Dependency-Inversion Principle
  • Cloud Computing
    • 👶Microsoft Azure 101
      • สมัคร Microsoft Azure
      • รู้จักกับ Resource Groups
      • สร้างเว็บตัวแรกกัน
      • สร้าง Virtual Machine กัน
      • ประเภทของคลาว์เซอร์วิส
      • มาสร้าง Logic App กัน
      • มาสร้าง Function App กัน
      • คลาว์คิดเงินยังไง ?
      • Cloud Native
      • Guideline for Cloud scaling
      • Auto Scaling
    • 👶Azure App Services
    • 👶App Service Plan
    • 👶Azure Storage
      • Blob storage
        • ลองสร้างที่เก็บไฟล์กันเลย
        • เข้าใจ Blob storage ให้มากขึ้น
        • ลองเขียนโค้ดอัพโหลดไฟล์กันบ้าง
        • สร้างเว็บจากที่ฝากไฟล์บนคลาว์
    • 👶Azure Bot Service
      • Bot เข้าใจเราได้ยังไงกันนะ
    • 👶Azure Cognitive Services
      • การสร้าง Cognitive Services
      • การ Login ด้วยใบหน้า
      • อ่านลายมือจากรูปเป็นตัวอักษร (OCR)
      • เขียน AI แยกของต่างๆทำยังไง?
      • เขียนแอพ ทายอายุ บอกเพศ ง่ายจิ๊ดเดียว
      • เขียนแอพให้ AI อธิบายรูปเป็นภาษาคน
    • 👶Machine Learning Studio
      • มาสร้าง AI ของแท้ตัวแรกของเรากัน
      • สร้าง AI ตัดสินใจอนุมัติบัตรเครดิต 💳
      • ลองเรียกใช้ AI ของเรากัน
    • 👶Azure Service Fabric
      • สร้าง Service Fabric กัน
    • 👶Blockchain
      • Blockchain ทำงานยังไง ?
      • Consensus Algorithm คืออะไร ?
      • สร้าง Blockchain ใช้เองกัน !
      • หัดเขียน Smart Contract กัน
    • 👶Power BI
    • 👶Azure Web App
      • เซิฟเวอร์บนคลาว์ ราคา? ต่าง?
    • 👶Azure DevOps
      • เล่น Azure DevOps กัน
      • เล่นกับ Repository
      • ลองทำ Continuous Integration (CI)
      • ลองทำ Continuous Delivery (CD)
      • เล่น Kanban Board
    • 🤠Cloud Playground
      • การป้องกันความลับหลุดตอนที่ 1
      • การป้องกันความลับหลุดตอนที่ 2
      • การป้องกันความลับหลุดตอนที่ 3
      • การป้องกันความลับหลุดตอนจบ
  • Software Testing
    • 👦Test-First Design
    • 👦Test-Driven Development
      • 1.มารู้จักกับ TDD กันดีกว่า
      • 2.Test cases เขาเขียนกันยังไงนะ
      • 3.เครื่องมือในการทดสอบ
      • 4.การใช้ Theory และ InlineData
      • 5.โค้ดที่ทดสอบได้
      • 6.Mantra of TDD
      • 7.Functional & None-Functional testing
      • 8.Manual vs Automation testing
      • 9.Automation Frameworks in .NET
      • 10.Mock Framework
      • 11.มาเรียนการใช้ Moq กันเถอะ
      • 12.สรุป
  • Web
    • 👦Web API
      • 1.Web API คืออะไร
      • 2.ติดตั้ง .NET Core SDK
      • 3.สร้าง Web API ตัวแรกกัน
      • 4.Verbs
      • 5.Swagger เพื่อคู่ API
      • 6.การใช้ Model
      • 7.เรียก Web API ผ่าน Postman
      • 8.มาจัดกลุ่ม API กัน (1/2)
      • 9.มาจัดกลุ่ม API กัน (2/2)
  • Software Design
    • 🤴Design Patterns
      • 🦈Creational patterns
        • Abstract Factory
        • Builder
        • Factory Method
        • Prototype
        • Singleton
      • 🦈Structural patterns
        • Adapter
        • Bridge
        • Decorator
        • Facade
        • Proxy
      • 🦈Behavioral patterns
        • Chain of Responsibility
        • Command
        • Iterator
        • Mediator
        • Memento
        • Observer
        • State
        • Strategy
        • Template Method
        • Visitor
Powered by GitBook
On this page
  • 🤔 มันคืออะไร ?
  • 🤨 ก็ยัง งง อยู่ดีขอตัวอย่างหน่อย
  • 😢 ปัญหา
  • 😄 วิธีแก้ปัญหา
  • 😵 Inheritance คือไรกันแน่ ?
  • Inheritance (การสืบทอด)
  • Base class (คลาสแม่)
  • Sub class (คลาสลูก)
  • Generalization
  • Override (การเปลี่ยนพฤติกรรม)
  • 🤔 ทำ Inheritance ไปทำไม ?
  • ความสัมพันธ์แบบ Is a
  • ลำดับชั้น
  • 🎥 วีดีโอประกอบความเข้าใจ
  • ทฤษฎี
  • ตัวอย่างการใช้งาน
  • ตัวอย่างโค้ดทั้งหมด

Was this helpful?

Export as PDF
  1. มือใหม่หัดเขียนโค้ด
  2. OOP

Inheritance

PreviousAbstraction & EncapsulationNextPolymorphism

Last updated 5 years ago

Was this helpful?

🤔 มันคืออะไร ?

คำว่า Inheritance มีใช้อยู่ในหลายวงการเลย แต่ในวงการซอฟต์แวร์ใน Wikipedia ถูกเขียนไว้ว่า

Inheritance is the mechanism of basing an or upon another object () or class (), retaining similar implementation. Also defined as deriving new classes () from existing ones (super class or ) and forming them into a hierarchy of classes. In most class-based object-oriented languages, an object created through inheritance (a "child object") acquires all the properties and behaviors of the parent object (except: , destructor, and of the base class). Inheritance allows programmers to create classes that are built upon existing classes, to specify a new implementation while maintaining the same behaviors (), to and to independently extend original software via public classes and interfaces. The relationships of objects or classes through inheritance give rise to a . Inheritance was invented in 1969 for .

😑 แค่อ่านก็ปวดกบาลละ แต่ก็ถอดหัวใจสำคัญของมันออกมาได้ว่า

Inheritance คือการสืบทอดคุณสมบัติ จาก Model A ไปยัง Model อื่นๆได้ ซึ่งมันจะช่วยให้เราเพิ่มความสามารถใหม่ๆเข้าไปได้โดยที่ไม่ต้องไปยุ่งกับโค้ดเก่าที่เคยเขียนไว้

🤨 ก็ยัง งง อยู่ดีขอตัวอย่างหน่อย

😢 ปัญหา

สมมุติว่าเราต้องเขียน โปรแกรมบัญชีธนาคาร ซึ่งบัญชีออมทรัพย์สามารถเก็บข้อมูล เงินในบัญชี และ เจ้าของบัญชี ได้ และอย่าลืมนะว่าเราต้อง ฝากเงินเข้าบัญชี ได้ด้วย ดังนั้นเราก็น่าจะได้ Model ออกมาประมาณนี้

public class SavingAccount
{
    private double balance;
    public double Balance { get => balance; }
    public string OwnerName { get; set; }

    public void Deposit(double amount)
    {
        if (amount > 0)
        {
            balance += amount;
        }
    }
}

ซึ่งบัญชีมันไม่ได้มีแค่ประเภทเดียวนะ เช่น บัญชีกระแสรายวัน ซึ่งมันก็ต้องเก็บข้อมูล เงินในบัญชี, เจ้าของบัญชี, ฝากเงินเข้าบัญชี ได้เหมือนกันด้วย ดังนั้นเราก็จะสร้าง Model ขึ้นมาอีกตัวหน้าตาประมาณนี้

public class CurrentAccount
{
    private double balance;
    public double Balance { get => balance; }
    public string OwnerName { get; set; }

    public void Deposit(double amount)
    {
        if (amount > 0)
        {
            balance += amount;
        }
    }
}

เราจะเห็นว่าโค้ด บัญชีออมทรัพย์ และ บัญชีกระแสรายวัน มันเหมือนกันเลย! ซึ่งถามว่าผิดไหม คำตอบคือไม่ผิดครับ แต่ถ้าเราปล่อยมันไว้แบบนี้เราจะมีปัญหาในอนาคต เช่น ถ้าบัญชีแต่ละประเภทต้องเก็บรหัสประชาชนเข้าไปด้วยล่ะ หรือ เรามาพบทีหลังว่าโค้ดมันเขียนผิดนะ แต่เราก็ copy ไปวางไว้ที่อื่นเรียบร้อยแล้ว

😄 วิธีแก้ปัญหา

เราสามารถนำหลักการ Inheritance มาช่วยในเรื่องนี้ได้ โดยการสร้าง Model ต้นแบบ ขึ้นมา แล้วทำการย้ายของที่ซ้ำกันไปไว้ในตัวต้นแบบตัวนั้น ซึ่งในตัวอย่างของที่เรากำลังทำอยู่มันคือ บัญชีธนาคาร ดังนั้นเราเลยสร้างคลาส BankAccount ขึ้นมาใหม่

public class BankAccount
{
}

แล้วทำการย้ายของที่มันซ้ำกันจาก บัญชีออมทรัพย์ กับ **บัญชีกระแสรายวัน มาไว้ในตัวต้นแบบซะ

public class BankAccount
{
    private double balance;
    public double Balance { get => balance; }
    public string OwnerName { get; set; }

    public void Deposit(double amount)
    {
        if (amount > 0)
        {
            balance += amount;
        }
    }
}

สุดท้ายเราก็สั่งให้ บัญชีออมทรัพย์ และ บัญชีกระแสรายวัน ไปสืบทอดความสามารถมาจากตัวต้นแบบที่สร้างไว้

public class SavingAccount : BankAccount
{
}

public class CurrentAccount : BankAccount
{
}

เพียงเท่านี้ บัญชีออมทรัพย์ และ บัญชีกระแสรายวัน ก็จะมีความสามารถทุกอย่างที่ตัวต้นแบบมีนั่นเอง ดังนั้นลองเขียนโค้ดเล่นกับบัญชีทั้ง 2 ตัวของเราดู

var sa = new SavingAccount();
sa.OwnerName = "(Saving) Saladpuk";
sa.Deposit(500);
Console.WriteLine($"{sa.OwnerName}, has THB {sa.Balance}.");

var ca = new CurrentAccount();
ca.OwnerName = "(Current) Saladpuk";
ca.Deposit(700);
Console.WriteLine($"{ca.OwnerName}, has THB {ca.Balance}.");

Output (Saving) Saladpuk, has THB 500. (Current) Saladpuk, has THB 700.

😵 Inheritance คือไรกันแน่ ?

Inheritance มันมีหลายเรื่องอยู่ในนั้นเยอะเลย ดังนั้นมาค่อยๆทำความเข้าใจกันทีละเรื่องก่อนละกันนะ โดยสิ่งที่เราต้องรู้สิ่งแรกคือ

Inheritance (การสืบทอด)

✨ เราสามารถนำคลาสที่มีอยู่แล้ว มาต่อยอดความสามารถให้กับคลาสใหม่ได้

เราได้เห็นตัวอย่างโค้ดด้านบนไปแล้วว่า บัญชีออมทรัพย์ และ บัญชีกระแสรายวัน ได้ต่อยอดความสามารถจาก BankAccount มา เลยทำให้บัญชีทั้ง 2 ประเภทมี OwnerName, Balance และ Deposit() ทั้งๆที่ตัวมันเองไม่ได้มีโค้ดอะไรอยู่ด้านในเลย ซึ่งสิ่งนี้เราเรียกว่า การสืบทอด หรือ Inheritance นั่นเอง

Base class (คลาสแม่)

โดยคลาสที่เป็นต้นแบบเราเรียกมันว่า Base class (บางตำราจะเรียกว่า Super class, Parent class บลาๆ) ซึ่งในตัวอย่างนี้คลาส BankAccount เป็น base class ของ SavingAccount และ CurrentAccount นั่นเอง

Sub class (คลาสลูก)

ส่วนคลาสที่ไปสืบทอดความสามารถจากคนอื่นเราเรียกมันว่า Sub Class (บางตำราเรียกว่า Derived class, Child class บลาๆ) ซึ่งในตัวอย่างนี้คลาส SavingAccount และ CurrentAccount เป็น sub class ของ BankAccount นั่นเอง

Generalization

✨ ของที่อยู่ใน Base class จะถูกส่งลงมาให้ Sub class ส่วน sub class จะใช้มันได้หรือเปล่าขึ้นอยู่กับ accessibility ของ property พวกนั้น

เราจะเห็นว่าแม้ SavingAccount จะไม่ได้เขียนโค้ดอะไรไว้ข้างในเลย แต่เราก็จะสามารถเรียกใช้ Balance หรือเมธอต Deposit ได้ ตามโค้ดด้านล่าง

var sa = new SavingAccount();
sa.OwnerName = "(Saving) Saladpuk";
sa.Deposit(500);

เพราะสิ่งที่คลาสแม่มี คลาสลูกจะมีด้วย แต่จะใช้งานได้หรือเปล่าขึ้นอยู่กับ accessibility ที่ตัวแม่ตั้งไว้ เช่นตัวแปร balance มันเป็น private คลาสลูกจะไม่สามารถอ้างถึงได้นั่นเอง

Override (การเปลี่ยนพฤติกรรม)

อีกสิ่งหนึ่งที่เราได้จากการทำ Inheritance นั่นคือ เราสามารถทำให้การทำงานของ Sub class ทำงานแตกต่างกันกับ Base class ของมันได้ เช่น ตัวชัญชีนั้นจะต้องสามารถ ถอนเงิน ได้ ซึ่งจุดที่น่าสนใจของมันคือ

  • บัญชีออมทรัพย์ - ถอนเงินได้สูงสุดไม่เกินเงินที่มีอยู่ในบัญชี

  • บัญชีกระแสรายวัน - ถอนเงินได้เกินเงินที่มีอยู่ในบัญชี แต่ไม่เกินวงเงินที่ตั้งไว้

ดังนั้นเราก็จะทำการเขียนโค้ดถอนเงินไว้ที่ตัว BankAccount ที่เป็น Base class ของมันก่อน ซึ่งได้ประมาณนี้

public class BankAccount
{
    ...

    public double Balance
    {
        get => balance;
        protected set => balance = value;
    }

    public virtual void Withdraw(double amount)
    {
        if (amount <= balance)
        {
            balance -= amount;
        }
    }
}

คำสั่ง virtual เป็นคำสั่งพิเศษของภาษา C# เพื่อที่จะให้ Sub class สามารถไปแก้ไขการทำงานของเมธอตนั้นๆได้ และผมได้แก้ให้ตัวแปร Balance สามารถเข้าไปแก้ไขผ่าน Sub class ได้เท่านั้น

เพียงเท่านี้เราก็จะสามารถถอนเงินได้ละ ส่วน บัญชีกระแสรายวัน เราก็ไปเขียนเพิ่มให้มันสามารถถอนเงินได้เกินเงินที่มี อยู่ในบัญชี ซึ่งสมมุติว่าวงเงินกู้ได้ไม่เกิน 1,000 ละกัน ดังนั้นเราก็จะได้โค้ดออกมาตามนี้

public class CurrentAccount : BankAccount
{
    private double credit = 1000;
    public override void Withdraw(double amount)
    {
        if (amount <= Balance + credit)
        {
            Balance -= amount;
        }
    }
}

ลองทดสอบกันดู

static void Main(string[] args)
{
    var sa = new SavingAccount();
    sa.OwnerName = "(Saving) Saladpuk";
    sa.Deposit(500);
    sa.Withdraw(700);
    Console.WriteLine($"{sa.OwnerName}, has THB {sa.Balance}.");

    var ca = new CurrentAccount();
    ca.OwnerName = "(Current) Saladpuk";
    ca.Deposit(700);
    ca.Withdraw(1000);
    Console.WriteLine($"{ca.OwnerName}, has THB {ca.Balance}.");
}

Output (Saving) Saladpuk, has THB 500. (Current) Saladpuk, has THB -300.

เรียบร้อยแล้ว บัญชีออมทรัพย์ ถอนเงินได้ไม่เกินเงินที่มีอยู่ในบัญชี แต่ในขณะที่ บัญชีกระแสรายวันถอนเกินเงินที่มีอยู่ได้นั่นเอง

🤔 ทำ Inheritance ไปทำไม ?

กลับมาที่บัญชีธนาคารเหมือนเดิม ซึ่งนอกจากการฝากเงินแล้ว เรายังต้องทำให้มัน ปิดบัญชี ได้ด้วย ซึ่งถ้าเราใช้ความสามารถของ Inheritance เราเลยสามารถไปเขียนเมธอตในการปิดบัญชีไว้ที่ Base class เพียงที่เดียว แล้วเจ้า Sub class ของมันก็จะได้รับความสามารถนี้ไปด้วยทันทีนั่นเอง (ขอเขียนแบบย่อๆนะ)

public class BankAccount
{
    ...

    private bool isClosed;
    public bool IsClosed { get => isClosed; }

    public void CloseAccount()
    {
        isClosed = true;
    }
}

ความสัมพันธ์แบบ Is a

เมื่อไหร่ก็ตามที่เราใช้ Inheritance ปุ๊ป เจ้าพวก Sub class ทั้งหลายจะมีความสัมพันธ์ที่เรียกว่า "Is a" ทันที หมายความว่า เราก็จะมองว่า บัญชีออมทรัพย์ และ บัญชีกระแสรายวัน มันเป็น บัญชีธนาคาร ประเภทหนึ่งทันที ซึ่งมันจะมีบทบาทที่สำคัญในเรื่องของการนำไปใช้กับ Polymorphism ในบทถัดไปอย่างมาก

ข้อควรระวัง อย่าใช้ Inheritance เพราะเราขี้เกียจเขียนโค้ดซ้ำๆ เพราะมันจะได้ความสัมพันธ์แบบ Is A เข้าไปด้วย (เดี๋ยวไปดูความร้ายแรงของมันในบทของ Polymorphism เอาละกัน)

จงทำ Inheritance เมื่อ Class พวกนั้นมันเป็นประเภทเดียวกันจริงๆ จากมุมมองของ Abstraction เท่านั้น

ลำดับชั้น

ในการทำ Inheritance มันจะมีลำดับชั้นความสัมพันธ์กันว่าใครเป็น คลาสแม่ คลาสลูก กันเสมอ ซึ่งจากโค้ดตัวอย่างด้านบนทั้งหมดก็สามารถเอามาเขียนเป็นแผนภาพ UML ง่ายๆได้ประมาณนี้

โดยเราจะเห็นว่า BankAccount เป็นคลาสแม่ ซึ่งมีลูก 2 ตัวคือ SavingAccount และ CurrentAccount

แต่มันยังไม่จบเพียงเท่านี้เพราะทุกคลาสจริงๆมันจะสืบสอดมาจากคลาสที่ชื่อว่า Object อีกที ดังนั้นแผนภาพที่แท้จริงคือ

ซึ่งจากรูปนี้คลาส BankAccount ก็เป็นคลาสลูกของคลาส Object อีกต่อหนึ่งนั่งเอง เลยทำให้มันมีความสามารถต่างๆของคลาสแม่ติดมาด้วยเสมอยังไงล่ะ เช่น เราใช้คำสั่ง .ToString() ได้เลยนั่นเอง

static void Main(string[] args)
{
    var acc = new BankAccount();
    acc.OwnerName = "Saladpuk";
    acc.Deposit(500);

    var result = acc.ToString();
    Console.WriteLine(result);
}

Output demo.BankAccount

หมายเหตุ: โดยปรกติ .ToString() ที่เขียนไว้ใน Base Class จะเป็นการแสดงชื่อเต็มๆโดยขึ้นต้นจาก Name space แล้วต่อด้วยชื่อคลาสของเรานั่นเอง

หมายเหตุ ใน C# เราสามารถทำการสืบทอดได้ทีละ 1 คลาสเท่านั้น หรือพูดง่ายๆคือ มีแม่ได้เพียงคนเดียว นะจ๊ะ แต่ในหลักการเรื่องนี้มันมีอีกหลายแบบเลย เช่น มีแม่ได้มากกว่า 1 ตัว (Multiple Inheritance) แบบลูกครึ่ง (Hybrid inheritance) ซึ่งเรื่องเหล่านั้นลองไปหาอ่านดูเอาเองต่อนะจ๊ะ

🎥 วีดีโอประกอบความเข้าใจ

ทฤษฎี

ตัวอย่างการใช้งาน

ตัวอย่างโค้ดทั้งหมด

public class BankAccount
{
    private bool isClosed;
    private double balance;

    public bool IsClosed { get => isClosed; }
    public double Balance
    {
        get => balance;
        protected set => balance = value;
    }
    public string OwnerName { get; set; }

    public void Deposit(double amount)
    {
        if (amount > 0)
        {
            balance += amount;
        }
    }

    public virtual void Withdraw(double amount)
    {
        if (amount <= balance)
        {
            balance -= amount;
        }
    }

    public void CloseAccount()
    {
        isClosed = true;
    }
}
public class SavingAccount : BankAccount
{
}
public class CurrentAccount : BankAccount
{
    private double credit = 1000;

    public override void Withdraw(double amount)
    {
        if (amount <= Balance + credit)
        {
            Balance -= amount;
        }
    }
}
static void Main(string[] args)
{
    var sa = new SavingAccount();
    sa.OwnerName = "(Saving) Saladpuk";
    sa.Deposit(500);
    sa.Withdraw(700);
    Console.WriteLine($"{sa.OwnerName}, has THB {sa.Balance}.");

    var ca = new CurrentAccount();
    ca.OwnerName = "(Current) Saladpuk";
    ca.Deposit(700);
    ca.Withdraw(1000);
    Console.WriteLine($"{ca.OwnerName}, has THB {ca.Balance}.");
}

Needless Repetition นี่คือตัวอย่างการเขียนโค้ดที่ไม่ดี นั่นคือการ copy งานที่เหมือนๆกันไปใช้ในแต่ละที่ ซึ่งหลักในการออกแบบที่ดี เราไม่ควรจะทำงานเดิมซ้ำ Don't Repeat Yourself (DRY) ซึ่งเพื่อนๆสามารถศึกษาเรื่อง Bad Code ได้จากบทความ

แนะนำให้อ่าน ใครที่สนใจอยากรู้การแปลงโค้ดให้เป็นภาพที่เข้าใจได้ง่ายๆ สามารถศึกษาเพิ่มเติมได้ที่บทความตัวนี้เลย

👦
💖
object
class
prototype-based inheritance
class-based inheritance
sub classes
base class
constructors
overloaded operators
friend functions
[1]
realizing an interface
reuse code
directed graph
Simula
[2]
👶 Code Smells
👶 UML พื้นฐาน