0Pricing
Kotlin Academy · บทเรียน

การมอบหมายเทียบกับการสืบทอด

เลือกใช้การประกอบ

การมอบหมายเทียบกับการสืบทอด เป็นบทเรียน Kotlin Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Kotlin Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน

สองวิธีในการนำกลับมาใช้ใหม่

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

คำแนะนำที่เป็นที่ยอมรับคือ เลือกการประกอบแทนการสืบทอด

ตัวอย่างการสืบทอด

เมื่อใช้การสืบทอด คลาสย่อยจะขยายคลาสฐานและแทนที่สมาชิกต่าง ๆ คลาสฐานต้องกำกับด้วย open ในภาษาคอตลิน

open class Animal {
    open fun sound() = "..."
}

class Dog : Animal() {
    override fun sound() = "woof"
}

fun main() {
    println(Dog().sound())
}

ตัวอย่างการมอบหมาย

การนำกลับมาใช้ซ้ำแบบเดิมด้วยการมอบหมาย: พฤติกรรมอยู่ในสมาชิกที่คลาสส่งต่อการทำงานให้

interface Sound { fun sound(): String }
class Bark : Sound { override fun sound() = "woof" }

class Dog(s: Sound) : Sound by s

fun main() {
    println(Dog(Bark()).sound())
}

คลาสฐานเปราะบาง

การสืบทอดเชื่อมโยงคลาสย่อยกับรายละเอียดภายในของคลาสแม่อย่างแน่นหนา การเปลี่ยนแปลงในคลาสฐานอาจทำให้คลาสย่อยเสียหายโดยไม่แสดงสัญญาณ — ปัญหาคลาสฐานเปราะบาง การมอบหมายพึ่งพาเพียงส่วนติดต่อ

การห่อหุ้ม

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

interface Counter { fun increment(): Int }

class SimpleCounter : Counter {
    private var n = 0
    override fun increment(): Int { n++; return n }
}

class GuardedCounter(private val c: Counter) : Counter by c {
    override fun increment(): Int {
        println("incrementing")
        return c.increment()
    }
}

fun main() {
    val g = GuardedCounter(SimpleCounter())
    println(g.increment())
    println(g.increment())
}

ความยืดหยุ่นขณะทำงาน

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

interface Clock { fun now(): Int }
class RealClock : Clock { override fun now() = 100 }
class FakeClock : Clock { override fun now() = 0 }

class Timer(c: Clock) : Clock by c

fun main() {
    println(Timer(RealClock()).now())
    println(Timer(FakeClock()).now()) // easy to test
}

พฤติกรรมหลายรูปแบบ

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

interface Walk { fun walk() = "walking" }
interface Swim { fun swim() = "swimming" }
class Walker : Walk
class Swimmer : Swim

class Amphibian : Walk by Walker(), Swim by Swimmer()

fun main() {
    val a = Amphibian()
    println(a.walk() + ", " + a.swim())
}

เมื่อใดจึงเหมาะกับการสืบทอด

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

sealed class Shape
class Circle(val r: Double) : Shape()
class Square(val s: Double) : Shape()

fun area(shape: Shape) = when (shape) {
    is Circle -> 3.14 * shape.r * shape.r
    is Square -> shape.s * shape.s
}

fun main() {
    println(area(Circle(2.0)))
}

เมื่อใดจึงเหมาะกับการมอบหมาย

เลือกใช้การมอบหมายเมื่อคุณต้องการ:

  • นำพฤติกรรมกลับมาใช้ซ้ำข้ามชนิดที่ไม่เกี่ยวข้องกัน
  • รวมความสามารถหลายอย่าง
  • รักษาการเชื่อมโยงให้หลวมและทำให้การทดสอบง่าย
  • ห่อหุ้มและตกแต่งการนำไปใช้ที่มีอยู่

เปรียบเทียบโดยตรง

การสืบทอด: คลาสแม่หนึ่งคลาส การเชื่อมโยงแน่นหนา กำหนดตายตัวขณะคอมไพล์ เป็น การมอบหมาย: ผู้ร่วมงานหลายราย การเชื่อมโยงหลวม สลับเปลี่ยนได้ขณะทำงาน มี ภาษา Kotlin ทำให้การมอบหมายมีต้นทุนต่ำด้วย by จึงทำให้น้ำหนักเอนเข้าหาการประกอบ

แนวทางเริ่มต้นที่ใช้ได้จริง

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

ตรวจสอบอย่างรวดเร็ว

ทดสอบความเข้าใจของคุณเกี่ยวกับการมอบหมายและการสืบทอด

สรุปทบทวน

คุณได้เปรียบเทียบแนวทางทั้งสองแบบ:

  • การสืบทอด: เป็น คลาสแม่หนึ่งคลาส การเชื่อมโยงแน่นหนา
  • การมอบหมาย: มี ผู้ร่วมงานหลายราย การเชื่อมโยงหลวม
  • ควรเลือกการประกอบ และใช้การสืบทอดกับลำดับชั้นแบบเป็นที่มั่นคง

ถัดไป: รูปแบบตัวตกแต่งที่ใช้การมอบหมายในทางปฏิบัติ

คำถามที่พบบ่อย

บทเรียน “การมอบหมายเทียบกับการสืบทอด” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การมอบหมายเทียบกับการสืบทอด” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Kotlin Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การมอบหมายเทียบกับการสืบทอด”

เลือกใช้การประกอบ คุณปฏิบัติ Kotlin Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Kotlin Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Kotlin Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “การมอบหมายเทียบกับการสืบทอด” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Kotlin Academy นี้ได้ไหม

ได้ บทเรียน Kotlin Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. คีย์เวิร์ด by
  2. การมอบหมายให้สมาชิก
  3. การมอบหมายเทียบกับการสืบทอด
  4. รูปแบบเชิงปฏิบัติ
← กลับไปที่ Kotlin Academy