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
  • 🔥 Polymorphism
  • 💖 Abstraction + Encapsulation
  • 👎 Bad Design
  • 👍 Good Design
  • 🎯 บทสรุป

Was this helpful?

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

Inheritance & Polymorphism

PreviousPolymorphismNextลองเขียน OOP ดูดิ๊

Last updated 4 years ago

Was this helpful?

หลังจากที่เข้าใจหลักการของ Inheritance กับ Polymorphism กันไปเรียบร้อยแล้ว ดังนั้นเรามาสรุปความเข้าใจเจ้า 2 ตัวนี้ก่อนว่ามันเกี่ยวเนื่องกันยังไง

🔥 Inheritance

เป็นการนำ Model ที่มีอยู่แล้วไปสร้างรูปแบบการทำงานใหม่ๆได้

🔥 Polymorphism

เป็นการรองรับให้ object สามารถอยู่ได้หลากหลายรูปแบบ และทำงานกับ object ที่แท้จริงของมัน

💖 Abstraction + Encapsulation

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

ข้อควรระวัง

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

  • ให้ใช้ Inheritance เมื่อมันเป็นของประเภทเดียวกันเท่านั้น

👎 Bad Design

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

public class Book
{
   public int Id { get; set; }
   public string Name { get; set; }
   public DateTime CreatedDate { get; set; }
   public string ISBN { get; set; }
   public string Author { get; set; }
}

public class Cat
{
   public int Id { get; set; }
   public string Name { get; set; }
   public DateTime CreatedDate { get; set; }
   public string OwnerName { get; set; }
}

public class Member
{
   public int Id { get; set; }
   public string Name { get; set; }
   public DateTime CreatedDate { get; set; }
   public string LastName { get; set; }
   public string Address { get; set; }
}

หลายครั้งที่เราจะพบว่า Developer จะมองว่า มันมีของที่เหมือนกัน ดังนั้นก็ใช้ Inheritance ซิมันจะได้ลดโค้ดที่ซ้ำกันออก กลายเป็นแบบนี้

public class ProductInformation
{
   public int Id { get; set; }
   public string Name { get; set; }
   public DateTime CreatedDate { get; set; }
}

public class Book : ProductInformation
{
   public string ISBN { get; set; }
   public string Author { get; set; }
}

public class Cat : ProductInformation
{
   public string Ownername { get; set; }
}

public class Member : ProductInformation
{
   public string LastName { get; set; }
   public string Address { get; set; }
}

ซึ่งมันก็ทำงานได้นะ ลดโค้ดที่ซ้ำกันได้ด้วยแต่ มันใช้ของผิดวัตถุประสงค์ (เฟร้ยยยย) มันเหมือนกับเรากำลังเอาตะเกียบไปกินไอติม ซึ่งดูผิวเผินก็คีบกินได้ไม่มีไร แต่ถ้าปล่อยทำแบบนี้ต่อไปเรื่อยๆ เมื่อไหร่ที่ไอติมละลายเราก็จะกินต่อไม่ได้นั่นเอง เมื่อเทียบกลับมาที่โค้ดด้านบน มันก็จะทำงานได้ แต่ถ้าปล่อยไปเรื่อยๆมีการใช้ของแบบนี้ต่อไปเรื่อยๆเดี๋ยวมันจะมีปัญหาตามมาอีกที เพราะในกรนี้นี้เราใช้ inheritance โดยไม่ได้คำนึงถึงความสัมพันธ์แบบ IS A ยังไงล่ะ

🤨 ยังไม่เข้าใจอ่ะ การใช้ความสัมพันธ์แบบ IS A แบบไม่ถูกมันจะมีปัญหาไร?

IS A ถ้าแปลเป็นภาษาไทยมันแปลได้ว่า "มันเป็น" นั่นเอง ซึ่งลองเอา Model ตามโค้ดด้านบนมาดูนะว่ามันฟังแล้วมันแปลกๆหรือเปล่า

  1. Book IS A ProductInformation - หนังสือเป็นข้อมูลสินค้าประเภทหนึ่ง

  2. Cat IS A ProductInformation - แมวเป็นข้อมูลสินค้าประเภทหนึ่ง

  3. Member IS A ProductInformation - สมาชิกเป็นข้อมูลสินค้าประเภทหนึ่ง

จากด้านบนข้อ 1 กับ 2 อ่านแล้วยังพอเข้าใจได้ เพราะเราขาย หนังสือ และ ขายแมว ดังนั้นทั้ง 2 อย่างนี้ยังพอเข้าใจได้ แต่ข้อ 3 สมาชิกมันไม่ใช่ข้อมูลสินค้าแน่ๆ แต่เนื่องจากเราเอา Inheritance มาใช้ มันเลยทำให้มันเกิดความสัมพันธ์แบบนั้นเกิดขึ้น ดังนั้นในอนาคตมันจะเกิดปัญหาขึ้นโดยไม่ตั้งใจได้

เช่น เราจะสร้าง Method เอาไว้คิดเงินละว่าสินค้าที่เลือกเข้ามาทั้งหมดราคาเท่าไหร่ ซึ่งเราก็อาจจะเขียนแบบง่ายๆออกมาเป็น

public double GetTotalPrice(ProductInformation[] products)
{
   ...
}

เนื่องจากเราทำเป็น Inheritance ดังนั้นมันเลยได้ความสามารถของ Polymorphism เข้ามาด้วย เลยทำให้เราสามารถส่ง object ที่เป็น Book และ Cat เข้ามาใน method ตัวนี้ได้ ... แต่ก็อย่าลืมนะว่ามันก็ส่ง object Member เข้ามาคิดราคาได้ด้วยเหมือนกัน!!

👍 Good Design

จากตัวอย่างแอพขายหนังสือและแมวโดยมีระบบสมาชิกถ้าเราจะออกแบบให้ดีนั้นมันมีหลักการง่ายๆแค่

มันมีเหตุผลอะไรที่ต้องใช้ Inheritance ไหม? ใช้แล้วได้ประโยชน์อะไร? จำเป็นจริงๆหรือเปล่า?

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

แต่ถ้าได้คำตอบซึ่งมีเหตุผลรองรับที่ดีแล้วล่ะก็ ใช้ได้เลย แต่จงทำให้ถูกในมุมของความสัมพันธ์ด้วย เช่น ถ้าหนังสือและแมว มันเป็นสินค้าในร้าน เราจะให้มันมาจาก Base class ที่เป็น Product ก็ได้

public class ProductInformation
{
   public int Id { get; set; }
   public string Name { get; set; }
   public DateTime CreatedDate { get; set; }
}

public class Book : ProductInformation
{
   public string ISBN { get; set; }
   public string Author { get; set; }
}

public class Cat : ProductInformation
{
   public string OwnerName { get; set; }
}

ส่วนเจ้าสมาชิกถ้ามันมี Model แค่ตัวนี้ตัวเดียวก็ปล่อยไปแบบเดิมก็ได้ อย่าไปทำอะไรที่มันซับซ้อนเลย

public class Member
{
   public int Id { get; set; }
   public string Name { get; set; }
   public DateTime CreatedDate { get; set; }
   public string LastName { get; set; }
   public string Address { get; set; }
}

แต่ถ้าเรามีสมาชิกหลายแบบ เช่น VIP หรืออะไรก็แล้วแต่ ให้เราถามคำถามเดิมต่อว่า มันมีเหตุผลอะไรที่ควรจะต้องทำ Inheritance ไหม? ซึ่งถ้าไม่มี ผมเสนอว่าทำตัวแปรมาคัดแยกประเภทเอาจะง่ายกว่า ไม่ซับซ้อนด้วย

public class Member
{
   public int Id { get; set; }
   public string Name { get; set; }
   public DateTime CreatedDate { get; set; }
   public string LastName { get; set; }
   public string Address { get; set; }

   public bool IsVIP { get; set; }
}

แต่ถ้าเรามีเหตุผลที่เพียงพอก็จะแตกกลุ่มออกมาอีกก็ได้

public class Membership
{
   public int Id { get; set; }
   public string Name { get; set; }
   public DateTime CreatedDate { get; set; }
   public string LastName { get; set; }
   public string Address { get; set; }
}

public class NormalMember : Membership
{
}

public class VIPMember : Membership
{
   public DateTime ExpiredDate { get; set; }
}

สมมุติว่าเรามีเหตุผลที่ดีพอในการทำ Inheritance แล้วล่ะก็ อย่าลืมเอาความสัมพันธ์มันมาตรวจสอบดีๆอีกครั้งด้วยล่ะ ดังนั้นเราลองเอาแผนภาพ UML มาดูคร่าวๆกัน

ลองตรวจความสัมพันธ์ของแต่ละกลุ่มดูว่ามันเหมาะสมหรือยัง

กลุ่มสินค้า

  1. หนังสือ เป็น สินค้าประเภทหนึ่ง

  2. แมว เป็น สินค้าประเภทหนึ่ง

กลุ่มสมาชิก

  1. สมาชิกธรรมดา เป็น สมาชิกประเภทหนึ่ง

  2. สมาชิก VIP เป็น สมาชิกประเภทหนึ่ง

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

จะทำ Inheritance ให้มองย้อนถึง IS A Relationship ก่อนทำเสมอ และ เหตุผลที่มีน้ำหนักคุ้มที่จะทำ

🎯 บทสรุป

การใช้ Inheritance & Polymorphism นั้นจะช่วยทำให้โค้ดเรามีความยืดหยุ่นเพิ่มขึ้นในหลายๆด้าน แต่ก็แลกมาด้วยความซับซ้อนที่สูงขึ้น และการออกแบบที่ต้องระวังมากขึ้น ซึ่งมันจะเป็นจุดที่ทำให้แอพเราแก้ไขปรับปรุงได้ยากขึ้นหลายเท่าตัว ดังนั้นก่อนใช้อะไรก็ตามแต่ให้คำนึงถึง ความเหมาะสม และข้อดีข้อเสียด้วยว่าคุ้มหรือไม่

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

แนะนำให้อ่าน หลักในการออกแบบขั้นพื้นฐาน หรือที่เราเรียกว่า SOLID Design เพื่อนๆสามารถไปศึกษาอ่านได้จากลิงค์ด้านล่างนี้เบย

👦
🏆
👦 SOLID Design Principles