เรียนรู้แนวคิดเกี่ยวกับ Classes และ object instances ในภาษา Kotlin

บทความนี้เกี่ยวกับแนวคิดของ class และ object instances ในภาษา Kotlin อธิบายให้เข้าใจง่าย ๆ ด้วยการนึกภาพถึงการทอยลูกเต๋า แทนที่จะทอยลูกเต๋าจริง ๆ เราสามารถเขียนโปรแกรมที่จำลองการทอยลูกเต๋าได้ เราจะทดลองสร้างแอปทอยลูกเต๋า (Dice Roller app) เป็น Android แอปที่ผู้ใช้สามารถคลิกปุ่มในแอปเพื่อทอยลูกเต๋าได้ มาเริ่มกันเลย!

แต่ละครั้งที่เราทอยลูกเต๋า สำหรับลูกเต๋า 6 เหลี่ยมปกติ ผลลัพธ์อาจเป็นตัวเลขใดก็ได้ภายในช่วงของค่าที่เป็นไปได้ คือ 1, 2, 3, 4, 5 และ 6 เราต้องมีวิธีที่จะแสดงค่าทั้งหมดนี้อย่างถูกต้อง

เราสามารถใช้ฟังก์ชันที่เรียกว่า random () เพื่อสร้างและส่งคืนตัวเลขสุ่มสำหรับช่วงที่กำหนดได้

val randomNumber = (1..6).random()

เรากำลังเรียก random () บนช่วง 1..6 โดยใช้จุดระหว่างช่วงและการเรียกฟังก์ชัน สามารถอ่านได้ว่า “สร้างตัวเลขสุ่มจากช่วง 1..6” จากนั้นผลลัพธ์จะถูกเก็บไว้ในตัวแปร randomNumber

1..6 เป็นช่วงของ Kotlin เนื่องจากมีตัวเลขเริ่มต้น, จุดสองจุด, ตามด้วยตัวเลขสิ้นสุด (ไม่มีช่องว่าง) ช่วงสามารถอยู่ระหว่างจำนวนเต็มใดก็ได้ เช่น 3..46, 0..270, -6 .. + 6, -10 ..- 4

val rollButton: Button = findViewById(R.id.button)
rollButton.setOnClickListener {
     // A 6-sided dice and roll it
     val randomNumber = (1..6).random()

     // Update the screen with the dice roll
     val resultTextView: TextView = findViewById(R.id.textView)
     resultTextView.text = randomNumber.toString()
}


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

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

จาก class ดังกล่าว เราสามารถสร้างวัตถุที่เป็นลูกเต๋าจริง ๆ ได้ เรียกว่า object instances ยกตัวอย่างเช่น เราสามารถสร้างลูกเต๋าที่มี 4 ด้านหรือ 12 ด้านได้

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

การจัดทุกอย่างที่เกี่ยวกับลูกเต๋าไว้ใน class เรียกว่า encapsulation, encapsulation เป็นคำในจินตนาการที่ใหญ่มาก แต่โดยรวมมันมายถึงเราสามารถรวมฟังก์ชันการทำงานที่เกี่ยวข้องกันอย่างมีเหตุผลไว้ในที่เดียวได้

ตอนนี้เรามาสร้าง class และ object instance กัน

สร้าง class ใหม่ที่เรียกว่า Dice เพื่อแทนลูกเต๋าที่หมุนได้

class Dice {}

ภายใน class เราสามารถระบุคุณสมบัติต่าง ๆ สำหรับ class โดยใช้ตัวแปร ลูกเต๋าจริงสามารถมีจำนวนด้าน, สี, หรือน้ำหนัก แต่ในตอนนี้เราจะสนใจที่จำนวนด้านของลูกเต๋า สำหรับจำนวนด้านที่ลูกเต๋าของเราจะมีตอนนี้คือ 6 ด้าน

var numSide = 6

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

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

fun roll(): Int { return (1..numSide).random() }

class Dice {
     var numSide = 6

     fun roll(): Int {
          return (1..numSide).random()
     }
}


ด้วย Dice class นี้ เราจะมีพิมพ์เขียวของสิ่งที่เป็นลูกเต๋า เพื่อให้มีลูกเต๋าที่แท้จริงในโปรแกรมของเรา เราต้องสร้าง object instance ของ Dice และถ้าเราต้องการมีลูกเต๋า 3 ลูก เราจะต้องสร้าง object instance 3 ครั้ง myFirstDice, mySecondDice, myThirdDice

val myFirstDice = Dice()

สังเกตวงเล็บหลังชื่อ class ซึ่งแสดงว่าเรากำลังสร้าง object instance ใหม่จากคลาส

ตอนนี้เรามี myFirstDice เป็น object ที่สร้างจากพิมพ์เขียวซึ่งเราสามารถเข้าถึงคุณสมบัติของมันได้ คุณสมบัติเดียวของลูกเต๋าที่มีใน class ตอนนี้คือจำนวนด้าน และเราเปลี่ยนจำนวนด้านให้ลูกเต๋าของเรามี 12 ด้าน เพราะลูกเต๋าไม่จำเป็นต้องมีแค่ 6 ด้าน มันสามารถมีรูปทรงและขนาดได้ตั้งแต่ 4 ด้าน 8 ด้าน สูงสุดคือ 120 ด้าน!

myFirstDice.numSide = 12

เราทอยลูกเต๋าที่เราสร้าง โดยเรียกฟังก์ชัน roll () บน myFirstDice

val diceRoll = myFirstDice.roll()

fun rollDice() {
     val myFirstDice = Dice()
     myFirstDice.numSide = 12
     val diceRoll = myFirstDice.roll()

     val resultTextView: TextView = findViewById(R.id.textView)
     resultTextView.text = diceRoll.toString()
}


ตอนนี้เรามีพิมพ์เขียวของลูกเต๋า (Dice class) และมีลูกเต๋าจริงที่มี 12 ด้าน (myFirstDice)

แนวคิดของ class คือการเป็นตัวแทนของสิ่งหนึ่งซึ่งมักเป็นสิ่งที่มีอยู่จริงในโลกแห่งความเป็นจริง ซึ่งในกรณีนี้ Dice class เป็นตัวแทนของลูกเต๋าที่มีอยู่จริง ในโลกแห่งความเป็นจริงลูกเต๋าลูกหนึ่งไม่สามารถเปลี่ยนจำนวนด้านได้ หากเราต้องการจำนวนด้านที่แตกต่างกันเราต้องสร้างลูกเต๋าที่แตกต่างกัน โดยทางโปรแกรมหมายความว่าแทนที่จะเปลี่ยนคุณสมบัติจำนวนด้านของ object instance ของ Dice ที่มีอยู่ เราควรสร้าง object instance ของลูกเต๋าใหม่พร้อมจำนวนด้านที่เราต้องการ

มาปรับปรุง class และการสร้าง object instance ของเรากัน

แก้ไข Dice class เพื่อให้สามารถระบุจำนวนด้านได้เมื่อเราสร้าง object instance ใหม่

class Dice (val numSide: Int) {}

สร้าง object instance ของ Dice พร้อมกับระบุจำนวนด้าน

val dice = Dice(6)

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val rollButton: Button = findViewById(R.id.button)
        rollButton.setOnClickListener {
            rollDice()
        }
    }

    private fun rollDice() {
        // Create new Dice object with 6 sides and roll it
        val dice = Dice(6)
        val diceRoll = dice.roll()

        // Update the screen with the dice roll
        val resultTextView: TextView = findViewById(R.id.textView)
        resultTextView.text = diceRoll.toString()
    }

    class Dice(private val numSide: Int) {
        fun roll(): Int {
            return (1..numSide).random()
        }
    }
}


เสร็จเรียบร้อยแล้วกับการสร้าง Dice class พร้อมดัวยตัวแปร numSide และฟังก์ชัน roll () เราได้สร้าง object instance ของ Dice ใหม่ จากนั้นก็เรียกฟังก์ชัน roll () เพื่อสร้างตัวเลขสุ่ม

ขอขอบคุณ Google Developers Training team