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

คลาสข้อมูลและคลาสปิด

ใช้คลาสข้อมูลสำหรับการตรวจสอบความเท่ากันตามค่าและ copy() และใช้คลาสปิดสำหรับลำดับชั้นชนิดข้อมูลที่ครอบคลุมทุกกรณีและการจำลองสถานะอย่างเป็นระเบียบ

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

คลาสข้อมูลคืออะไร

คลาสข้อมูลใน Kotlin คือคลาสที่มีจุดประสงค์หลักเพื่อเก็บข้อมูล ตัวคอมไพเลอร์จะสร้างเมธอดที่มีประโยชน์ให้โดยอัตโนมัติ:

  • equals() — เปรียบเทียบอินสแตนซ์สองรายการด้วยค่า
  • hashCode() — แฮชที่สอดคล้องกันโดยอิงจากคุณสมบัติ
  • toString() — รูปแบบสตริงที่อ่านได้ง่าย
  • copy() — สร้างสำเนาที่แก้ไขแล้ว
  • รองรับการแยกโครงสร้าง

การประกาศคลาสข้อมูล

เพิ่มคีย์เวิร์ด data ไว้หน้า class คุณสมบัติทั้งหมดต้องอยู่ในตัวสร้างหลัก:

data class User(val id: Int, val name: String, val email: String)

fun main() {
    val u1 = User(1, "Alice", "alice@example.com")
    val u2 = User(1, "Alice", "alice@example.com")

    println(u1)          // User(id=1, name=Alice, email=alice@example.com)
    println(u1 == u2)    // true  (value equality)
    println(u1 === u2)   // false (different objects)
}

copy() — แก้ไขฟิลด์หนึ่งรายการ

copy() จะสร้างอินสแตนซ์ใหม่โดยเปลี่ยนคุณสมบัติบางรายการ อินสแตนซ์เดิมจะไม่ถูกแก้ไข (ความไม่เปลี่ยนแปลง):

data class Product(val name: String, val price: Double, val inStock: Boolean)

fun main() {
    val original = Product("Laptop", 999.0, true)

    // Only change the price; keep everything else
    val onSale = original.copy(price = 799.0)

    println(original)  // Product(name=Laptop, price=999.0, inStock=true)
    println(onSale)    // Product(name=Laptop, price=799.0, inStock=true)
}

การประกาศแบบแยกโครงสร้าง

คลาสข้อมูลรองรับการแยกโครงสร้าง — แยกคุณสมบัติไปเป็นตัวแปรโดยใช้ฟังก์ชัน componentN() ที่คอมไพเลอร์สร้างขึ้น:

data class Point(val x: Int, val y: Int)

fun main() {
    val point = Point(10, 20)

    // Destructure into separate variables
    val (x, y) = point
    println("x=$x, y=$y")   // x=10, y=20

    // Also works in for loops with maps
    val scores = mapOf("Alice" to 95, "Bob" to 88)
    for ((name, score) in scores) {
        println("$name: $score")
    }
}

คลาสปิดผนึกคืออะไร

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

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

ไวยากรณ์คลาสปิดผนึก

ประกาศคลาสย่อยไว้โดยตรงภายในคลาสหรือในไฟล์เดียวกัน:

sealed class NetworkResult<out T> {
    data class Success<T>(val data: T) : NetworkResult<T>()
    data class Error(val message: String, val code: Int = 0) : NetworkResult<Nothing>()
    object Loading : NetworkResult<Nothing>()
}

fun handle(result: NetworkResult<String>) {
    when (result) {
        is NetworkResult.Success -> println("Data: ${result.data}")
        is NetworkResult.Error  -> println("Error ${result.code}: ${result.message}")
        NetworkResult.Loading   -> println("Loading...")
    }
}

คลาสปิดผนึก + when (ครอบคลุมครบถ้วน)

จุดเด่นของคลาสปิดผนึกคือ when จะครอบคลุมครบถ้วน คอมไพเลอร์จะบังคับให้คุณจัดการกับประเภทย่อยทุกประเภท จึงไม่มีกรณีใดถูกลืม:

sealed class UiState {
    object Loading : UiState()
    data class Success(val message: String) : UiState()
    data class Error(val error: String) : UiState()
}

fun render(state: UiState): String = when (state) {
    is UiState.Loading      -> "Showing spinner"
    is UiState.Success      -> "Show: ${state.message}"
    is UiState.Error        -> "Error: ${state.error}"
    // Compiler error if you remove any branch!
}

fun main() {
    println(render(UiState.Loading))
    println(render(UiState.Success("Loaded!")))
}

คลาสปิดผนึกเทียบกับ Enum

ทั้งสองอย่างใช้แทนชุดค่าที่กำหนดตายตัว แต่มีความแตกต่างดังนี้:

  • Enum — ค่าคงที่แต่ละค่าคืออินสแตนซ์เดียว และไม่มีข้อมูลเพิ่มเติมสำหรับแต่ละรูปแบบ
  • คลาสปิดผนึก — แต่ละรูปแบบสามารถเก็บข้อมูลที่แตกต่างกัน และอาจเป็นคลาสหรือออบเจ็กต์

ใช้ enum เมื่อรูปแบบต่าง ๆ ไม่จำเป็นต้องมีข้อมูล ใช้คลาสปิดผนึกเมื่อรูปแบบต่าง ๆ ต้องมีคุณสมบัติที่แตกต่างกัน

การประกาศออบเจ็กต์ (ซิงเกิลตัน)

object จะสร้างซิงเกิลตัน — มีอินสแตนซ์เดียว สร้างเมื่อจำเป็น และปลอดภัยต่อการทำงานหลายเธรด:

object AppConfig {
    const val BASE_URL = "https://api.example.com"
    const val TIMEOUT = 30L

    fun buildUrl(path: String) = "$BASE_URL/$path"
}

fun main() {
    println(AppConfig.BASE_URL)          // https://api.example.com
    println(AppConfig.buildUrl("users")) // https://api.example.com/users
}

ออบเจ็กต์ประกอบ

ออบเจ็กต์ประกอบอยู่ภายในคลาสและจัดเตรียมสมาชิกระดับคลาส (คล้ายกับ static ของ Java) โดยทั่วไปมักใช้กับเมธอดสร้างอินสแตนซ์:

class Token private constructor(val value: String) {
    companion object {
        fun create(raw: String): Token {
            val cleaned = raw.trim()
            require(cleaned.isNotEmpty()) { "Token must not be blank" }
            return Token(cleaned)
        }
    }
}

fun main() {
    val token = Token.create("  abc123  ")
    println(token.value)  // abc123
}

คลาสข้อมูลในแอปจริง

ผสานคลาสข้อมูลเข้ากับคลาสปิดผนึกเพื่อสร้างแบบจำลองสถานะที่เป็นระเบียบ:

data class Post(val id: Int, val title: String, val body: String)

sealed class PostState {
    object Loading : PostState()
    data class Loaded(val posts: List<Post>) : PostState()
    data class Failed(val reason: String) : PostState()
}

fun showState(state: PostState) = when (state) {
    PostState.Loading        -> println("Fetching posts...")
    is PostState.Loaded      -> println("${state.posts.size} posts loaded")
    is PostState.Failed      -> println("Failed: ${state.reason}")
}

fun main() {
    showState(PostState.Loaded(listOf(
        Post(1, "Hello", "World"),
        Post(2, "Kotlin", "Rocks")
    )))
}

ตรวจสอบความเข้าใจ

ข้อความใดอธิบายความแตกต่างระหว่างคลาสปิดผนึกกับคลาสนามธรรมทั่วไปได้ดีที่สุด

สรุป: คลาสข้อมูลและคลาสปิดผนึก

ตอนนี้คุณมีเครื่องมืออันทรงพลังของ Kotlin สองชนิด:

  • data class — การเทียบความเท่ากันตามค่า, copy(), การแยกโครงสร้าง และ toString() ที่สร้างขึ้นโดยอัตโนมัติ
  • คลาสปิดผนึก — ลำดับชั้นประเภทที่มีจำนวนจำกัด, when ที่ครอบคลุมครบถ้วน และแต่ละรูปแบบสามารถเก็บข้อมูลของตนเอง
  • object — ซิงเกิลตัน และออบเจ็กต์ประกอบสำหรับเมธอดสร้างอินสแตนซ์

เมื่อใช้ร่วมกัน รูปแบบเหล่านี้จะแทนที่โค้ดส่วนเกินของ Java และช่วยให้สร้างแบบจำลองสถานะได้อย่างเป็นระเบียบและปลอดภัย

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

บทเรียน “คลาสข้อมูลและคลาสปิด” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “คลาสข้อมูลและคลาสปิด”

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

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

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

บทเรียน “คลาสข้อมูลและคลาสปิด” ใช้เวลานานแค่ไหน

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

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

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

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

  1. ความปลอดภัยของค่า Null
  2. คลาสและออบเจ็กต์
  3. คลาสข้อมูลและคลาสปิด
  4. ฟังก์ชันขยายและฟังก์ชันลำดับสูง
← กลับไปที่ Android Academy