OOP
Class ใน C++ คืออะไร
ในภาษา C++ class คือชนิดข้อมูลที่ผู้ใช้สามารถกำหนดขึ้นเองได้ เปรียบเสมือน “พิมพ์เขียว” สำหรับการสร้าง object โดย class ทำหน้าที่รวมเอาข้อมูล และ function ที่ทำงานกับข้อมูลนั้นๆเข้าไว้ด้วยกัน
คุณสมบัติสำคัญของ Class
- Data Encapsulation class จะรวมข้อมูลต่างๆ (ตัวแปร) และ method เข้าไว้ด้วยกันเป็นหน่วยเดียว โดยการซ่อนข้อมูลเอาไว้ อันเป็นหลักการที่ซ่อนรายละเอียดภายในของ class จากภายนอก โดยจะเปิดเผยเฉพาะส่วนที่จำเป็นต้องใช้เท่านั้น
- มี Constructors เป็น method พิเศษที่จะถูกเรียกใช้งานโดยอัตโนมัติเมื่อมีการสร้าง object ขึ้นมา มีหน้าที่กำหนดค่าเริ่มต้นให้กับคุณสมบัติ (attributes) ของ Object ส่วน Destructors จะถูกเรียกเมื่อ Object สิ้นสุดช่วงเวลาของมัน โดยมีหน้าที่ปลดปล่อยทรัพยากรที่ Object นั้นใช้
- มีตัวระบุการเข้าถึง โดย class จะใช้ตัวระบุการเข้าถึงหรือ 'สิทธิ์การเข้าถึง' (public, protected, private) เพื่อควบคุมการเข้าถึงสมาชิกต่างๆ โดย public สามารถเข้าถึงได้จากทุกที่, protected เข้าถึงได้เฉพาะใน class ลูกที่สืบทอดมา, ส่วน private เข้าถึงได้เฉพาะภายใน class ที่ประกาศเท่านั้น
- การสืบทอด (Inheritance) Class นั้นสามารถสืบทอดคุณสมบัติและพฤติกรรมของ class อื่นได้ เราเรียกอีก class นั้นว่า base class และ class ที่สืบทอดมาเป็น derived class (class ลูก) การสืบทอดเช่นนี้ช่วยทำให้สามารถนำ code ใน class เดิมกลับมาใช้ใหม่ได้ โดยไม่จำเป็นต้องเขียน code ใหม่อยู่ตลอดได้
- ความหลากหลายเชิงรูปแบบ (Polymorphism) ภาษา C++ สนับสนุน polymorphism ผ่านการสืบทอดและ virtual functions ทำให้เราสามารถมอง Object ที่อยู่ใน class แตกต่างกันเสมือนอยู่ใน base class เดียวกันได้ อีกทั้งยังทำให้ส่วนติดต่อแบบเดียวกัน (interface) สามารถสื่อถึงข้อมูลหรือชนิดข้อมูลที่แตกต่างกันออกไปได้
- มี Member Functions คือ function ที่ประกาศอยู่ภายใน class และสามารถเข้าถึงสมาชิกต่างๆของ class ได้ เราสามารถระบุได้ว่าจะให้ method นั้นเป็น const (ค่าคงที่ ที่ไม่สามารถแก้ไขตัว object), static (ใช้ร่วมกันโดยทุก Object ของ class), หรือ virtual (เพื่อสนับสนุนคุณสมบัติ polymorphism ใน OOP)
ตัวอย่างการใช้ class
#include <iostream>
#include <string>
using namespace std;
class Person {
public: // Access specifier
// Attributes
string name;
int age;
// Constructor
Person(string n, int a) : name(n), age(a) {}
// Method
void greet() const {
cout << "Hello, my name is " << name << " and I am " << age
<< " years old." << endl;
}
};
int main() {
// Creating an object of the Person class
Person person1("Alice", 30);
// Calling a method of the object
person1.greet();
return 0;
}
ตัวอย่างจาก code ด้านบนนี้ แสดงให้เห็นว่า
- class
Person
ทำการห่อหุ้มคุณสมบัติต่างๆ (ชื่อและอายุ) เอาไว้ - มี method สำหรับการทำงาน (
greet
) และ constructor เป็นตัวที่คอยกำหนดค่าเริ่มต้นให้กับคุณสมบัติของ Object ตอนที่ objectPerson
นั้นถูกสร้างขึ้นมา - ในขณะที่ method
greet
จะใช้คุณสมบัติเหล่านั้นเพื่อแสดงข้อความสวัสดี (เป็นค่าที่ดึงมาจากที่ set ผ่าน constructor เข้ามา) - สิ่งที่เห็นนี้ช่วยให้รู้ว่า class ในภาษา C++ สามารถสร้างแบบจำลองของสิ่งที่มีอยู่ในโลกความเป็นจริงได้อย่างไร โดยการจัดกลุ่มข้อมูลและพฤติกรรมที่เกี่ยวข้องกันเข้าไว้ด้วยกัน
ตัวอย่างการใช้ class นี้เอง เราก็จะคุ้นๆตาจาก leet code มาเช่นกัน เนื่องจากใน leet code เองก็ใช้วิธีสร้าง class ในการรับข้อมูลไปใช้งานเช่นกัน
องค์ประกอบหลักของ Class
Instance
Instance ของ class คือการทำให้ class นั้นเกิดขึ้นจริงอย่างเป็นรูปธรรม ซึ่งจะถูกสร้างขึ้นในหน่วยความจำ โดยเราจะเรียกมันว่า object และมันจะห่อหุ้ม data members ที่ถูกนิยามไว้โดย class รวมถึงจะสามารถใช้ member functions ของมันได้
แต่ละ instance จะมีชุดค่า attribute เป็นของตัวเองซึ่งอาจแตกต่างจาก instances อื่น ทำให้เกิด data encapsulation และพฤติกรรมของ object ที่ไม่เหมือนกันออกมาได้
การสร้าง instance ของ class ประกอบด้วยการจัดสรรหน่วยความจำให้กับ object และการกำหนดค่าเริ่มต้นให้กับ attributes ของมัน โดยทั่วไปจะทำผ่าน constructor
นี่คือตัวอย่างของการประกาศ instance
class MyClass {
public:
MyClass() {} // Constructor
};
MyClass obj; // Creating an instance of MyClass named 'obj'
Constructor
Constructor คือ member function ชนิดพิเศษที่จะถูกเรียกใช้โดยอัตโนมัติเมื่อมีการสร้าง object ของ class นั้นขึ้นมา หน้าที่หลักของ constructor คือการกำหนดค่าเริ่มต้นให้กับ attribute ของ object โดย constructor จะมีชื่อเดียวกันกับ class และจะไม่คืนค่าใดๆกลับมาจากการเรียกใช้ constructor
จุดประสงค์ กำหนดค่าเริ่มต้นให้กับสถานะของ object (attributes) เมื่อมีการสร้างตัวอย่าง (instantiate) ขึ้นมา
คุณสมบัติ
- สามารถถูก overload เพื่อรองรับการกำหนดค่าเริ่มต้นของ object ได้หลากหลายรูปแบบ
- สามารถมี default parameter ได้
- class หนึ่งสามารถมี default constructor (ไม่มีพารามิเตอร์) ได้ ซึ่งจะถูกใช้ในกรณีที่ไม่ได้มีการกำหนด constructor อื่นขึ้นมา หรือไม่ได้ระบุ constructor อย่างเจาะจงตอนสร้าง object
นี่คือตัวอย่างของ constructor
#include <iostream>
using namespace std;
// Define a class named 'Rectangle'
class Rectangle {
public:
int width, height;
// Constructor with two parameters
Rectangle(int w, int h) {
width = w;
height = h;
}
// Member function to calculate area
int area() { return width * height; }
};
int main() {
// Create an instance of Rectangle with width=5 and height=10
Rectangle rect(5, 10);
// Call the 'area' function on the instance
cout << "Area of Rectangle: " << rect.area() << endl;
return 0;
}
อธิบาย code ด้านบน
- class
Rectangle
ถูกนิยามขึ้นมาพร้อมกับสมาชิกข้อมูล (data member) ที่เป็น public สองตัว (width และ height) และมี constructor สำหรับการสร้าง Object โดยที่ constructor จะรับพารามิเตอร์ 2 ตัว (w และ h) และทำการกำหนดค่าเริ่มต้นให้ความกว้าง (width) และความสูง (height) ของ Object ด้วยค่าที่ถูกส่งเข้ามา - constructor ในตัวอย่างนี้จะถูกนิยามในรูปแบบ
Rectangle(int w, int h)
ทำหน้าที่กำหนดค่าเริ่มต้นให้กับความกว้างและความสูงของ Object Rectangle ที่ถูกสร้างขึ้นมาใหม่ โดยใช้ค่าที่ได้รับเป็นพารามิเตอร์สำหรับการ set ค่าเริ่มต้นให ้กับ w, h - instance ของ class Rectangle ถูกสร้างด้วยคำสั่ง
Rectangle rect (5, 10);
โดยบรรทัดนี้จะเป็นการสร้าง Object ชื่อ rect ขึ้นมา ซึ่งมีชนิดข้อมูลเป็นRectangle
โดยคำสั่งนี้จะเรียกใช้ constructor พร้อมกับส่งค่า 5 และ 10 ไปเป็น argument ส่งผลให้ width และ height ของ Object rect ถูกตั้งค่าเป็น 5 และ 10 ตามลำดับ - มีการเรียกใช้ member function ชื่อ area จะถูกเรียกใช้กับตัวอย่าง rect ด้วยคำสั่ง
rect.area()
โดย function นี้จะคำนวณและคืนค่าพื้นที่ของรูปสี่เหลี่ยมออกมา
Attribute
Attributes หรือที่รู้จักกันอีกชื่อว่า data members หรือ fields คือตัวแปรที่เก็บข้อมูลต่างๆ ที่เกี่ยวข้องกับ object ที่ถูกสร้างขึ้นมาจาก class โดย attribute บ่งบอกถึงสถานะ (state) ของ object นั้นๆ
จุดประสงค์
- ทำหน้าที่จัดเก็บข้อมูลเกี่ยวกับ object หรือสถานะที่ object กำลังอยู่ในขณะนั้น
- Attributes สามารถกำหนดการเข้าถึงได้เป็น public, private หรือ protected ซึ่งมีผลควบคุมการเข้าถึง attribute นั้นๆจากภายนอก class (เดี๋ยวเราอธิบายเรื่องการเข้าถึงอีกที)
อธิบายเพิ่มเติมจากตัวอย่างด้านบนของ Rectangle
width และ height คือ Attribute ของ class Rectangle นั่นเอง
// Define a class named 'Rectangle'
class Rectangle {
public:
int width, height; // Attribute
// Constructor with two parameters
Rectangle(int w, int h) {
width = w;
height = h;
}
// Member function to calculate area
int area() { return width * height; }
};
Method
Methods หรือ member functions คือ function ที่ถูกนิยามไว้ภายใน class เพื่อให้สามารถทำงานกับ object ของ class นั้นๆได้ โดย method สามารถเข้าถึงและแก้ไขค่าของ attribute ต่างๆภายใน class รวมถึงเป็นตัวกำหนดพฤติกรรมการทำงานของ object
- จุดประสงค์
- กำหนดว่าจะมีการกระทำอะไรบ้างที่สามารถทำได้กับ object
- จัดเตรียมวิธีการในการโต้ตอบกับข้อมูลภายใน object
- ประเภทของ methods
- Accessor Methods (Getters) ทำหน้าที่คืนค่าของ attribute ที่ถูกกำหนดการเข้าถึงเป็น private
- Mutator Methods (Setters) ทำหน้าที่กำหนดค่า หรือแก้ไขค่าของ attribute ที่ถูกกำหนดการเข้าถึงเป็น private
- General Methods ทำหน้าที่อื่นๆที่เกี่ยวข้องกับการทำงานของ class
และนี่คื อตัวอย่างของการใช้ method ในแต่ละประเภท
#include <iostream>
using namespace std;
// Define a class named 'Student'
class Student {
private:
string name; // Private attribute
int age; // Private attribute
public:
// Constructor to initialize the attributes
Student(string n, int a) {
name = n;
age = a;
}
// Getter for the name
string getName() const { return name; }
// Setter for the name
void setName(string n) { name = n; }
// Getter for the age
int getAge() const { return age; }
// Setter for the age
void setAge(int a) { age = a; }
// General method to display student details
void displayDetails() {
cout << "Student Name: " << name << ", Age: " << age << endl;
}
};
int main() {
// Create an instance of Student
Student student1("John Doe", 20);
// Display initial details
student1.displayDetails();
// Modify the student's name and age using setters
student1.setName("Jane Doe");
student1.setAge(21);
// Display updated details
student1.displayDetails();
return 0;
}
อธิบายจาก code ด้านบน
- Class
Student
ถูกนิยามขึ้นมาพร้อมกับ attribute แบบ private สองตัวคือ name และ age โดย attribute ที่เป็น private จะสามารถเข้าถึงได้เฉพาะภายใน class ทำให้มั่นใจได้ในเรื่องของการห่อหุ้มข้อมูล (encapsulation) ว่าจะไม่โดนรบกวนจากภายนอกได้ - constructor ที่มีชื่อว่า
Student (string n, int a)
ทำหน้าที่กำหนดค่าเริ่มต้นให้กับ private attribute ที่ชื่อ name และ age ด้วยค่าที่ถูกส่งเข้ามา - class นี้จะมีทั้ง method แบบ getter และ setter สำหรับทั้ง name และ age โดยที่ getter (
getName
และgetAge
) ทำหน้าที่คืนค่าของ private attribute ในขณะที่ setter (setName
และsetAge
) ให้เราสามารถแก้ไขค่าของ private attribute ได้ วิธีการแบบนี้เป็นการห่อหุ้ม attribute และควบคุมการเข้าถึงค่า private เอาไว้ ไม่ให้สามารถแก้ไขจากภายนอกโดยตรงได้ - method
displayDetails
เป็น general method ที่ใช้ private attributes ในการแสดงรายละเอียดของนักเรียน (classStudent
) - และใน main function ทำการสร้าง instance ของ Student, แสดงรายละเอียดเริ่มต้น, ปรับเปลี่ยนค่าของ attribute ของ instance ด้วยการใช้ setter และจากนั้นแสดงรายละเอียดที่ถูกอัพเดทออกมาได้
ทีนี้เพื่อเติมเต็มความเข้าใจที่เพิ่มขึ้นจะขออธิบายเรื่องของ private และ public เพิ่มเติม
Public / Private
- Public สมาชิก (member) ที่ถูกประกาศเป็น
public
สามารถเข้าถึงได้จากทุกที่ที่อยู่นอก class ที่ Object นั้นถูกสร้างขึ้นมา หมายความว่า function หรือ class ภายนอกใดๆก็สามารถเข้าถึงและปรับเปลี่ยน public member ได้ - Private สมาชิกที่ถูกประกาศเป็น
private
จะเข้าถึงได้เฉพาะภายใน class นั้นๆเท่านั้น จะไม่สามารถเข้าถึงหรือเปลี่ยนแปลงค่าได้โดยตรงจากภายนอก class การเข้าถึง private member มักจะทำผ่าน public method ต่างๆ (เช่น ตัวอย่าง getters และ setters ในหัวข้อ method)
ตัวอย่าง code
#include <iostream>
using namespace std;
// Define a class named 'Person'
class Person {
private:
string name; // Private attribute: Not accessible outside the class directly
int age; // Private attribute: Not accessible outside the class directly
public:
// Public Constructor: Accessible from outside the class
Person(string n, int a) {
name = n;
age = a;
}
// Public method to set the name - demonstrates encapsulation
void setName(string n) {
name = n; // Can access private member within the class
}
// Public method to get the name
string getName() const {
return name; // Can access private member within the class
}
// Public method to display details of the person
void displayDetails() {
cout << "Name: " << name << ", Age: " << age << endl;
}
};
int main() {
// Create an instance of Person
Person person1("Alice", 30);
// Attempt to access public methods
cout << "Initial Details: " << endl;
person1.displayDetails();
// Set a new name using public setter method
person1.setName("Bob");
// Display updated details using public method
cout << "Updated Details: " << endl;
person1.displayDetails();
// Attempt to directly access private members (This will cause a compile-time
// error if uncommented) cout << person1.name; // ERROR: 'name' is private
// within this context
return 0;
}
ตัวอย่างการใช้งานแบบรวมกัน
นี่คือตัวอย่าง code C++ ที่แสดงให้เห็นถึงการใช้ constructors, attributes (data members), methods, สิทธิ์การเข้าถึงแบบ public และ private รวมถึงการสร้าง instances ภายใน class โดยตัวอย่างนี้จะใช้กับ class แบบง่ายๆชื่อว่า Car
#include <iostream>
#include <string>
using namespace std;
class Car {
public:
// Constructor
Car(string model, int year) : model(model), year(year) {}
// Public method to display car details
void displayInfo() const {
cout << "Car model: " << model << ", Year: " << year << endl;
}
// Public method to change the car's model
void setModel(string newModel) { model = newModel; }
// Public method to get the car's model
string getModel() const { return model; }
private:
// Private attributes
string model;
int year;
};
int main() {
// Creating an instance of Car
Car myCar("Toyota", 2020);
// Using a public method to display car information
myCar.displayInfo();
// Changing the model of the car
myCar.setModel("Honda");
// Displaying the updated car information
myCar.displayInfo();
return 0;
}
Explanation
- class
Car
ถูกนิยามขึ้นมาพร้อมด้วย attribute แบบ private 2 ตัว (model
และyear
) โดยมี constructor และ method แบบ public อีก 3 ตัว (displayInfo
,setModel
และgetModel
) - มี Constructor ที่มีชื่อ
Car(std::string model, int year)
ทำหน้าที่กำหนดค่าเริ่มต้นให้กับ objectCar
ด้วยค่า model และ year โดย constructor เป็น function พิเศษที่จะถูกเรียกใช้งานทุกครั้งที่มีการสร้าง instance ใหม่ของCar
- มี Attributes ชื่อ
model
และyear
ทำหน้าที่เก็บข้อมูลของแต่ละ instance ของ Car โดยจะถูกกำหนดสิทธิ์การเข้าถึงเป็น private หมายความว่าจะไม่สามารถเข้าถึงได้โดยตรงจากภายนอก class ได้ - Methods ที่มี
displayInfo()
เป็น method แบบ public ที่จะพิมพ์รายละเอียดของรถออกมาที่ console และสามารถเข้าถึง attribute ที่เป็น private ได้ เนื่องจากเป็ นสมาชิกของ classCar
ด้วยเช่นกันsetModel(std::string newModel)
ทำให้เราสามารถเปลี่ยนแปลง model ของรถได้ โดย method นี้จะทำการแก้ไขค่าของ attribute ชื่อ model ภายใน instance ตัวนั้นได้getModel()
ทำหน้าที่คืนค่า model ปัจจุบันของรถออกมา ถือเป็นตัวอย่างของ accessor method (หรือที่เรียกว่า getter) ซึ่งถือเป็นวิธีการที่ปลอดภัยในการอ่านค่าของ attribute ที่เป็น private
- Public and Private Access Specifiers
public
members (displayInfo
,setModel
,getModel
) สามารถเข้าถึงได้จากภายนอก class ทำให้เราสามารถโต้ตอบกับ object ของCar
ได้private
members (model
,year
) จะถูกห่อหุ้มไว้ภายใน class ทำหน้าที่ปกป้องสถานะภายในของ objectCar
จากการถูกแก้ไขจากภายนอก class
- การสร้าง instance ใน function
main()
มีการสร้าง instance ของ Car ชื่อว่าmyCar
โดยส่งค่าเริ่มต้นเข้าไปว่า "Toyota" และ 2020 ใน instance นี้จะสังเกตว่ามีการสร้างตัวอย่าง (instantiate) ขึ้นมาจาก class - การใช้ Public Methods ในตัวอย่างมีการใช้ method
displayInfo
และsetModel
เพื่อโต้ตอบกับ objectmyCar
ซึ่งตัวอย่างตรงนี้ช่วยให้เราเห็นว่า methods สามารถนำมาใช้ทำงานหรือเข้าถึงข้อมูลใน object ได้
และนี่คือตัวอย่างเบื้องต้นของ code แนว OOP โดยอ้างอิงผ่าน Class
OOP คืออะไร
Object-Oriented Programming (OOP) ในภาษา C++ เป็น programming paradigm ที่มีแนวคิด "objects" เป็นหัวใจสำคัญ ซึ่ง object นั้นสามารถเก็บข้อมูลในรูปของ fields (หรืออาจเรียกว่า attributes หรือ properties) และ code ในรูปของ procedures (หรืออาจเรียกว่า methods หรือ functions) OOP มีจุดมุ่งหมายเพื่อทำการจำลองสิ่งที่มีอยู่ในโลกความเป็นจริงลงมาในการเขียนโปรแกรม อย่างเช่น การสืบทอด (inheritance) การซ่อนข้อมูล (hiding) และ ความหลากหลายเชิงรูปแบบ (polymorphism) หลักการพื้นฐานสำคัญของ OOP ในภาษา C++ ได้แก่
1. Encapsulation Encapsulation คือกลไกที่ใช้จำกัดการเข้าถึงส่วนประกอบบางอย่างของ object และปกป้องการแก้ไขส่วนประกอบเหล่านั้นที่ไม่ได้รับอนุญาตไม่ให้สามารถเข้าถึงได้ โดยเราจะใช้ access specifiers (private, protected และ public) มาควบคุมการมองเห็นของสมาชิกของ class โดย Encapsulation จะช่วยในการนำเอาข้อมูลและ method ที่จะทำงานกับข้อมูลนั้นมารวมไว้เป็นหน่วยเดียวกันได้
2. Inheritance Inheritance คือการที่ class หนึ่งๆ (class ลูก) สามารถรับเอาคุณสมบัติหรือพฤติกรรมของ class อื่น (class แม่) ไปใช้งานได้ ซึ่งทำให้เราสามารถ Override (เขียนทับ) หรือต่อยอด (Extend) function ต่างๆได้ สิ่งนี้ช่วยเสริมการนำ code กลับมาใช้ใหม่ได้ และสร้างความสัมพันธ์แบบลำดับชั้นระหว่าง class ต่างๆออกมาได้
3. Abstraction Abstraction คือแนวคิดของการซ่อนรายละเอียดการทำงานที่ซับซ้อนเอาไว้ และแสดงเฉพาะ feature หลักๆของ object นั้นไว้เท่านั้น (ประกาศว่า class นั้นทำอะไรออกมาได้แค่นั้น) โดยในภาษา C++ abstraction สามารถทำได้โดยใช้ abstract class และ interface สิ่งนี้ทำให้เราสามารถมุ่งความสนใจไปที่ว่า object นั้นทำอะไร ไม่ใช่ว่ามันทำงานอย่างไร
4. Polymorphism Polymorphism ทำให้ส่วนติดต่อ interface หนึ่งๆสามารถสื่อถึง forms (หรือชนิดข้อมูล) ที่แตกต่างกันออกไปได้ ในภาษา C++ polymorphism สามารถทำได้ผ่านการใช้ function overloading, operator overloading และ virtual function โดย virtual function จะทำให้ override method ได้ สิ่งนี้ช่วยให้เราสามารถปฏิบัติกับ object ที่อยู่ในคนละ class เสมือนเป็น object ที่อยู่ใน superclass เดียวกันได้
นี่คือตัวอย่าง code ++ ที่ใช้คุณสมับิติ OOP
#include <iostream>
#include <string>
using namespace std;
// Base class
class Animal {
public:
virtual void
speak() const = 0; // Pure virtual function making Animal an abstract class
};
// Derived class
class Dog : public Animal {
public:
void speak() const override { cout << "Woof!" << endl; }
};
int main() {
Dog myDog;
myDog.speak(); // Polymorphism: Dog class overrides the speak method
return 0;
}
จากตัวอย่าง code นี้
- class
Animal
เป็น abstract base class ที่มี pure virtual function ชื่อspeak()
ซึ่งแสดงถึงหลักการ abstraction - ส่วน class
Dog
จะสืบทอดคุณสมบัติมาจากAnimal
และทำการ override (เขียนทับ) methodspeak()
ซึ่งตรงนี้จะเห็นหลักการ inheritance และ polymorphism - การใช้ access specifier (
public
) เป็นตัวอย่างของ encapsulation ซึ่งทำให้มั่นใจว่า methodspeak()
สามารถเข้าถึงได้จากภายนอก class ในขณะที่รายละเอียดการทำงานอื่นๆ อาจจะถูกซ่อนไว้ภายในของ class
OOP ในภาษา C++ ทำให้การสร้างโปรแกรมที่ซับซ้อนแต่สามารถจัดการได้ง่ายผ่านการมองของทุกอย่างออกเป็น object โดยสามารถสะท้อนพฤติกรรมและปฏิสัมพันธ์แบบที่อยู่ในโลกความเป็นจริงได้เช่นกัน
1. Encapsulation (การห่อหุ้ม)
Encapsulation เป็นแนวคิดพื้นฐานที่สำคัญของ OOP ซึ่งเป็นการรวมกลุ่มข้อมูล (attributes) และ method (functions) ที่ทำงานกับข้อมูลนั้นๆเข้าไว้ด้วยกันเป็นหน่วยเดียว เรียกว่า class นอกจากนี้ยังเป็นการจำกัดการเข้าถึงการทำงานภายในของ class ด้วย ซึ่งหลักการนี้เรียกว่าการซ่อนข้อมูล (data hiding)
Encapsulation เป็นการทำให้แน่ใจได้ว่าสถานะภายในของ object นั้นจะไม่สามารถเข้าถึงได้โดยตรงจากภายนอกได้ เราจำเป็นใช้งานกับข้อมูลข อง object ผ่านทาง method เท่านั้น
ประโยชน์ของ Encapsulation
- ควบคุมวิธีการเข้าถึงหรือแก้ไขข้อมูล
- เพิ่มความปลอดภัยให้กับสถานะภายในของ object
- สามารถเปลี่ยนแปลงการทำงานภายในโดยไม่กระทบกับส่วนอื่นๆของโปรแกรม
ตัวอย่างของ Encapsulation ในภาษา C++
เรามาดูตัวอย่างง่ายๆที่แสดงถึง encapsulation ในภาษา C++ กัน โดยเราจะใช้ class ชื่อ Person
ซึ่งจะห่อหุ้ม (encapsulate) ชื่อและอายุของคนหนึ่งเอาไว้ด้วยการควบคุมการเข้าถึงคุณสมบัติเหล่านี้ผ่านทาง public methods เอาไว้
#include <iostream>
#include <string>
using namespace std;
class Person {
private:
string name; // Private attribute
int age; // Private attribute
public:
// Constructor
Person(string n, int a) : name(n), age(a) {}
// Setter for age - Demonstrates validation
void setAge(int newAge) {
if (newAge >= 0) { // Ensure the new age is sensible
age = newAge;
}
}
// Getter for age
int getAge() const { return age; }
// Getter for name
string getName() const { return name; }
// A public method that uses private data
void greet() const {
cout << "Hello, my name is " << name << " and I am " << age
<< " years old." << endl;
}
};
int main() {
Person person("Alice", 30); // Create a Person object
person.greet(); // Access a public method
// Attempt to set an invalid age
person.setAge(-5);
// The age won't change due to validation in setAge
cout << person.getName() << "'s age is " << person.getAge() << endl;
return 0;
}
จาก code ด้านบน
- attribute ที่ชื่อ
name
และage
นั้นถูก set เป็น private ซึ่งทำให้ไม่สามารถเข้าถึงได้โดยตรงจากภายนอก class ได้ - method
setAge
,getAge
,getName
และgreet
ถูกกำหนดให้เป็น public ทำให้เราสามารถเข้าถึงข้อมูลส่วนตัว (private data) ได้ โดย methodsetAge
จะมีการตรวจสอบความถูกต้อง (validation) เพื่อป้องกันการกำหนดค่าอายุที่ไม่ถูกต้องด้วย (เช็คว่ามากกว่า 0 หรือไม่) - ผู้ที่ใช้ class
Person
จำเป็นต้องเข้าถึงข้อมูลของ object ผ่านทาง public methods เหล่านี้เท่านั้น ไม่สามารถเข้ามาแก้ไขข้อมูลโดยตรงได้ และทำให้มั่นใจได้ว่า การ set ข้อมูลที่เกิดขึ้น เกิดขึ้นอย่างถูกต้องแล้วผ่าน method ที่กำหนดเอาไว้แล้วเช่นกัน
2. Inheritance (การสืบทอด)
Inheritance เป็นกลไกที่เปิดช่องทางให้ class หนึ่งๆ (เรียกว่า derived class) สามารถสืบทอด attributes และ methods ต่างๆจากอีก class หนึ่ง (เรียกว่า base class) มาได้ ถือได้ว่าเป็นเสาหลักสำคัญของ OOP ที่อำนวยความสะดวกให้เกิดการนำ code กลับมาใช้ใหม่ได้ และสร้างลำดับชั้นโครงสร้างของ class ขึ้นมา
ประโยชน์ของ Inheritance
- Inheritance ส่งเสริมการนำ code ที่มีอยู่แล้วกลับมาใช้ได้ โดยที่ derived class สามารถสืบทอด properties และพฤติกรรมต่างๆที่เป็น public และ protected ทั้งหมดมาจาก base class ทำให้คุณสามารถเพิ่ม feature หรือจะ override (เขียนทับ) ของที่มีอยู่เดิมลงไปได้
- Inheritance สามารถสะท้อนธรรมชาติตามลำดับขั้นของสิ่งที่มีอยู่ในโลกความเป็นจริงได้ (ใครสืบทอดต่อจากใคร ใช้ของใคร มาจากใคร)
- support คุณสมบัติตัวอื่นๆ เช่น abstract, polymorphism