การมอบหมายให้สมาชิก
ประกอบพฤติกรรม
การมอบหมายให้สมาชิก เป็นบทเรียน Kotlin Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Kotlin Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน
การประกอบพฤติกรรม
ออบเจ็กต์จริงมักต้องรวมความสามารถหลายอย่างเข้าด้วยกัน แทนที่จะสืบทอดจากหลายแหล่ง คุณสามารถมอบหมายงานให้แต่ละความสามารถแก่ ออบเจ็กต์สมาชิกเฉพาะด้านได้
สองบทบาทในคลาสเดียว
สมมติว่าคลาสหนึ่งควรอ่านและเขียนได้ทั้งคู่ ให้กำหนดอินเทอร์เฟซสองรายการ แล้วมอบหมายงานให้การนำไปใช้ของแต่ละรายการแยกกัน
interface Reader { fun read(): String }
interface Writer { fun write(s: String): String }
class FileReader : Reader { override fun read() = "contents" }
class FileWriter : Writer { override fun write(s: String) = "wrote " + s }
class FileIO(r: Reader, w: Writer) : Reader by r, Writer by w
fun main() {
val io = FileIO(FileReader(), FileWriter())
println(io.read())
println(io.write("data"))
}ตัวรับมอบหมายหลายตัว
คลาสหนึ่งสามารถมอบหมายงานให้หลายอินเทอร์เฟซพร้อมกัน โดยแต่ละอินเทอร์เฟซมอบหมายให้สมาชิกคนละตัว คลาสจึงประกอบพฤติกรรมของสมาชิกเหล่านั้นได้โดยไม่ต้องสืบทอด
interface Logger { fun log(m: String): String }
interface Validator { fun valid(m: String): Boolean }
class ConsoleLogger : Logger { override fun log(m: String) = "LOG: " + m }
class LengthValidator : Validator { override fun valid(m: String) = m.isNotEmpty() }
class Service(l: Logger, v: Validator) : Logger by l, Validator by v
fun main() {
val s = Service(ConsoleLogger(), LengthValidator())
println(s.valid("hi"))
println(s.log("started"))
}จัดเก็บตัวรับมอบหมายเป็นสมาชิก
เมื่อต้องอ้างอิงตัวรับมอบหมายภายในการแทนที่ ให้เก็บตัวรับมอบหมายเป็นคุณสมบัติของตัวสร้าง อินสแตนซ์เดียวกันจะรองรับทั้งการส่งต่อและโค้ดที่คุณกำหนดเอง
interface Cache { fun get(k: String): String }
class MapCache : Cache {
override fun get(k: String) = "value-of-" + k
}
class TracingCache(private val inner: Cache) : Cache by inner {
override fun get(k: String): String {
println("lookup " + k)
return inner.get(k)
}
}
fun main() {
println(TracingCache(MapCache()).get("id"))
}ผสานการมอบหมายงานกับสถานะของตนเอง
คลาสที่มอบหมายงานสามารถเพิ่มคุณสมบัติและเมธอดของตนเองควบคู่กับส่วนที่ส่งต่อมา เพื่อเพิ่มความสามารถให้กับออบเจ็กต์ที่ประกอบขึ้น
interface Engine { fun start(): String }
class V8 : Engine { override fun start() = "vroom" }
class Car(e: Engine) : Engine by e {
var doors = 4
fun honk() = "beep"
}
fun main() {
val c = Car(V8())
println(c.start())
println(c.honk())
println(c.doors)
}สลับการนำไปใช้
เนื่องจากตัวรับมอบหมายเป็นเพียงสมาชิก คุณจึงสร้างตัวห่อหุ้มเดียวกันโดยใช้การนำไปใช้เบื้องหลังที่แตกต่างกันได้ และเลือกพฤติกรรมขณะทำงาน
interface Notifier { fun send(msg: String): String }
class EmailNotifier : Notifier { override fun send(msg: String) = "email: " + msg }
class SmsNotifier : Notifier { override fun send(msg: String) = "sms: " + msg }
class Alerts(n: Notifier) : Notifier by n
fun main() {
println(Alerts(EmailNotifier()).send("hi"))
println(Alerts(SmsNotifier()).send("hi"))
}การมอบหมายงานให้คุณสมบัติ
นิพจน์หลัง by อาจเป็นนิพจน์ใด ๆ ที่ประเมินค่าเพียงครั้งเดียว รวมถึงการเรียกตัวสร้างด้วย ไม่จำเป็นต้องเป็นพารามิเตอร์
interface Greeter { fun greet() = "hi" }
class DefaultGreeter : Greeter
class Page : Greeter by DefaultGreeter()
fun main() {
println(Page().greet())
}หลีกเลี่ยงปัญหาโครงสร้างเพชร
คลาสไม่สามารถสืบทอดพฤติกรรมจากหลายคลาสได้ แต่การมอบหมายงานให้หลายอินเทอร์เฟซผ่านสมาชิกที่แยกกันช่วยหลีกเลี่ยงปัญหาโครงสร้างเพชรแบบดั้งเดิมได้อย่างเรียบร้อย
interface A { fun a() = "A" }
interface B { fun b() = "B" }
class AImpl : A
class BImpl : B
class Combined : A by AImpl(), B by BImpl()
fun main() {
val c = Combined()
println(c.a() + c.b())
}การออกแบบเพื่อการประกอบ
เพื่อให้ประกอบได้ดี:
- กำหนดอินเทอร์เฟซขนาดเล็กที่มุ่งเน้นเฉพาะด้าน
- จัดเตรียมการนำไปใช้ที่นำกลับมาใช้ใหม่ได้
- มอบหมายงานให้แต่ละบทบาทในคลาสที่ทำหน้าที่ประกอบ
วิธีนี้ทำให้คลาสยืดหยุ่นและทดสอบได้
ทบทวนการมอบหมายงานให้สมาชิก
การมอบหมายงานให้กับออบเจ็กต์สมาชิกช่วยให้คลาสประกอบพฤติกรรมจากส่วนต่าง ๆ ได้ คุณสามารถรวมหลายอินเทอร์เฟซ แทนที่บางส่วน สลับการนำไปใช้ และเพิ่มสถานะของตนเองได้ทั้งหมดโดยไม่ต้องสืบทอด
ถัดไป: การเปรียบเทียบโดยตรง
คุณได้เห็นแล้วว่าการมอบหมายงานมีความยืดหยุ่นเพียงใด บทเรียนถัดไปจะเปรียบเทียบการมอบหมายงานกับการสืบทอดโดยตรง เพื่อให้คุณทราบว่าควรเลือกใช้แบบใด
ตรวจสอบความเข้าใจ
ทดสอบความเข้าใจเกี่ยวกับการมอบหมายงานให้สมาชิก
ทบทวน
คุณได้เรียนรู้การมอบหมายงานให้สมาชิก:
- มอบหมายงานให้หลายอินเทอร์เฟซผ่านออบเจ็กต์ที่แยกกัน
- แทนที่บางส่วนและเพิ่มสถานะของตนเอง
- สลับการนำไปใช้ขณะสร้าง
- หลีกเลี่ยงปัญหาจากการสืบทอดหลายทาง
ถัดไป: การมอบหมายงานเทียบกับการสืบทอด
คำถามที่พบบ่อย
บทเรียน “การมอบหมายให้สมาชิก” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การมอบหมายให้สมาชิก” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Kotlin Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การมอบหมายให้สมาชิก”
ประกอบพฤติกรรม คุณปฏิบัติ Kotlin Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Kotlin Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Kotlin Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “การมอบหมายให้สมาชิก” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Kotlin Academy นี้ได้ไหม
ได้ บทเรียน Kotlin Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- คีย์เวิร์ด by
- การมอบหมายให้สมาชิก
- การมอบหมายเทียบกับการสืบทอด
- รูปแบบเชิงปฏิบัติ