การมอบหมายเทียบกับการสืบทอด
เลือกใช้การประกอบ
การมอบหมายเทียบกับการสืบทอด เป็นบทเรียน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- คีย์เวิร์ด by
- การมอบหมายให้สมาชิก
- การมอบหมายเทียบกับการสืบทอด
- รูปแบบเชิงปฏิบัติ