Encapsulation

Encapsulation คืออะไร

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

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

Access Modifiers

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

public ตัวแปรสามารถเข้าถึงได้โดยโปรแกรมในส่วนเดียวกัน หรือจากโปรแกรมในส่วนอื่นๆ เช่น อยู่คนละ namespace หรือไฟล์

private ตัวแปรสามารถเข้าถึงได้โดยคลาสเดียวกันหรือ struct เดียวกัน

protected ตัวแปรสามารถเข้าถึงได้โดยคลาสเดียวกันหรือ struct เดียวกัน หรือในคลาสที่ได้รับการถ่ายทอด (inherit) มายัง

internal ตัวแปรสามารถเข้าถึงได้โดยโปรแกรมเดียวกันเท่านั้น หรือในคลาสเดียวกัน ไม่สามารถเข้าถึงจากภายนอกคลาสได้

คำสั่ง public และ private

ต่อไปมาดูตัวอย่างของการกำหนดระดับของการเข้าถึงในภาษา C# อย่างไรก็ตามคุณได้เห็นบ้างแล้วในบทเรียนที่ผ่านมา

using System;

namespace EncapsulationExample
{
    class Program
    {
        static void Main(string[] args)
        {
            Planet a = new Planet();
            a.name = "Mars";
            a.SetRadius(3390);

            Console.WriteLine("Planet name = " + a.name);
            Console.WriteLine("Radius = " + a.GetRadius() + " km");
            Console.WriteLine("Surface area ~ " + 
                a.GetSurfaceArea() / 10E5 + " million square km");

            Planet b = new Planet();
            b.name = "Earth";
            b.SetRadius(6371);

            Console.WriteLine("Planet name = " + b.name);
            Console.WriteLine("Radius = " + b.GetRadius() + " km");
            Console.WriteLine("Surface area ~ " +
                b.GetSurfaceArea() / 10E5 + " million square km");
        }
    }

    class Planet
    {

        public string name;
        private int radius;

        public void SetRadius(int r)
        {
            radius = r;
        }

        public int GetRadius()
        {
            return radius;
        }

        public float GetSurfaceArea()
        {
            return 4 * (22 / 7.0f) * radius * radius;
        }
    }
}

ในตัวอย่างด้านบน เป็นตัวอย่างการใช้ access modifier แบบ public และ private ในการสร้างตัวแปรที่อยูในคลาส Planet หลังจากนั้นเราไปสร้างออบเจ็คของคลาสนี้ในคลาสหลักของเรา ในคลาส Program เราได้สร้างออบเจ็ค a ในการเข้าถึงตัวแปร name ของออบเจ็คสามารถเข้าผ่านคำสั่ง a.name ได้ในทันที เพราะว่าตัวแปรนี้มีการกำหนดการเข้าถึงเป็นแบบ public ที่สามารถเข้าถึงจากภายนอกคลาสได้ เช่นในคำสั่ง

a.SetRadius(3390);
...
b.SetRadius(6371);

แต่สำหรับตัวแปร radius นั้นเนื่องจากระดับการเข้าถึงเป็น private ซึ่งไม่สามารถเข้าถึงจากภายนอกได้โดยตรง เราจะต้องเข้าถึงผ่านเมธอด SetRadius() และ GetRadius() ที่สร้างขึ้นในคลาสและกำหนดระดับการเข้าถึงให้กับฟังก์ชันเหล่านี้เป็น public หรือแนวคิดแบบนามธรรม จะกล่าวได้ว่าเราไม่ทราบว่าภายในนั้นมีตัวแปร radius อยู่ เราแค่ทำงานกับตัวแปรนี้ผ่านเมธอดที่เป็น public

Planet name = Mars
Radius = 3390 km
Surface area ~ 144.472112 million square km
Planet name = Earth
Radius = 6371 km
Surface area ~ 510.26976 million square km

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

รูปทรงสามมิติของทรงกลมที่แสดงรัศมีและพื้นผิว

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