# Encapsulation and Abstraction

## **Encapsulation**

&#x20;    Encapsulation คือ การรวมข้อมูลและเมดธอดที่ดำเนินการกับข้อมูลนี้เข้าเป็นหน่วยเดียว โดยจะ**ซ่อนข้อมูลไม่ให้เข้าถึงได้โดยตรง แต่จะอนุญาติให้เมดธอดภายใน class เดียวกันสามารถเข้าถึงข้อมูลนั้นได้** เพื่อป้องกันการเข้าถึงข้อมูลจากภายนอกและการนำไปใช้ในทางที่ผิด         &#x20;

![](/files/-MQwsQ7gjL6nq9DMTneG)

&#x20;    อย่างที่ทราบกันว่า class ประกอบไปด้วยสมาชิกตัวแปรและเมดธอด ซึ่งข้อมูลภายใน class ถูกกำหนดขอบเขตการใช้งานเป็น public เพื่อให้สามารถเข้าถึงข้อมูลจากภายนอก class นั่นหมายความว่า **object ในโปรแกรม สามารถเข้าถึงตัวแปรเพื่อเปลี่ยนแก้ไขข้อมูลได้โดยตรง** ดังตัวอย่างต่อไปนี้

{% tabs %}
{% tab title="Example class-object code C++" %}

```cpp
// oop_p2_1.cpp
#include <iostream>
#include <string>
using namespace std;

class Employee{
    public:
    int id;
    string name;
    double salary;
};

int main(){
    Employee emp1;
    emp1.id = 1;
    emp1.name = "James";
    emp1.salary = 15000;
    
    cout << "your name is " << emp1.name << endl;
    cout << "your salary is " << emp1.salary << endl;

    emp1.salary = -10000;
    
    cout << "your name is " << emp1.name << endl;
    cout << "your salary is " << emp1.salary << endl;
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Output" %}

```cpp
your name is James
your salary is 15000
your name is James
your salary is -10000
```

{% endtab %}
{% endtabs %}

&#x20;    เพื่อป้องการเข้าถึงข้อมูลจากภายนอก class จึงใช้การกำหนดขอบเขตการเข้าถึงของข้อมูลเป็น private  ทำให้ object อื่น ๆ ไม่สามารถเข้าถึงข้อมูลนั้นได้ วิธีนี้เรียกว่า การซ่อนข้อมูล แต่ข้อเสียของการกำหนดขอบเขตการเข้าถึงของข้อมูลเป็น private คือ ไม่สามารถนำข้อมูลออกมาแสดงผลหรือนำมาใช้งานได้ จึงต้องหาช่องทางอื่นในการเข้าถึงข้อมูลที่สามารถควบคุมความถูกต้องของข้อมูลนั้นได้ คือ การเข้าถึงข้อมูลผ่านการเรียกใช้เมธอด ดังตัวอย่างต่อไปนี้

{% tabs %}
{% tab title="Example Encapsulation code C++" %}

```cpp
// oop_p2_2.cpp
#include <iostream>
#include <string>
using namespace std;

class Employee{
    private:
    double salary;
    
    public:
    int id;
    string name;

    void setSalary(double base){
    if(base >= 15000 && base <= 100000 ){
        salary = base;
        } else {
            salary = 0;
        }
    }

    int getSalary(){
        return salary;
    }
};

int main(){
    Employee emp1;
    emp1.id = 1;
    emp1.name = "James";
    emp1.setSalary(18000);
    
    cout << "your name is " << emp1.name << endl;
    cout << "your salary is " << emp1.getSalary() << endl;

    emp1.name = "Conun";
    emp1.setSalary(1000000);
    
    cout << "your name is " << emp1.name << endl;
    cout << "your salary is " << emp1.getSalary() << endl;
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Output" %}

```cpp
your name is James
your salary is 18000
your name is Conun
your salary is 0
```

{% endtab %}
{% endtabs %}

&#x20;    จากตัวอย่างจะเห็นได้ว่าตัวแปร salary เป็นตัวแปรที่ถูกซ่อนด้วยการกำหนดขอบเขตการใช้งานเป็น private ทำให้ไม่สามารถเรียกใช้จากภายนอก class แต่ตัวแปรนี้สามารถเข้าถึงได้จากเมดธอด getSalary() และ setSalary() ที่มีอยู่ภายใน class เท่านั้น โดยที่เมดธอด getSalary() จะรับพารามิเตอร์ (parameter) ตัวเลขเข้ามาพิจารณาในเงื่อนไข หากเงื่อนไขเป็นจริง จะทำการเก็บค่านั้นลงในตัวแปร salary แต่ถ้าเงื่อนไขเป็นเท็จ จะเก็บค่า 0 ลงใน ตัวแปร salary แทนค่าที่รับมา ส่วนเมดธอด getSalary() จะทำหน้าที่ในการนำค่าที่ถูกเก็บไว้ในตัวแปร salary มาแสดงผล

{% hint style="success" %}
**คำถาม** ทำไมการประกาศเมดธอด getSalary() ถึงใช้ int แทนการใช้ void ?

**คำตอบ**  void คือ การประกาศฟังก์ชันที่ไม่มีการส่งค่าคืน

&#x20;              int คือ การประกาศฟังก์ชันที่ส่งค่าคืนเป็นตัวเลข

แหล่งอ้างอิง :: <https://www.w3schools.com/cpp/cpp_functions.asp>
{% endhint %}

## **Abstraction**

&#x20;    การให้ข้อมูลที่จำเป็นหรือข้อมูลที่ต้องการให้รู้แก่ภายนอก class  โดนใช้หลักแนวคิดจาก Encapsulation  แต่จะแตกต่างกันที่ Encapsulation จะซ่อนข้อมูลหรือตัวแปรไม่ให้เข้าถึงได้โดยตรง ส่วน Abstraction จะซ่อนกระบวนการทำงานหรือเมดธอดที่สำคัญบางส่วนไม่ให้เข้าถึงได้โดยตรง หมายความว่า ผู้ใช้จะสามารถเรียกใช้ได้เฉพาะเมดธอดที่ถูกกำหนดเป็น public ทั้งนี้ Abstraction มีการใช้งานอยู่ 2 แบบ คือ

### &#x20;1. Abstraction โดยใช้ Class

&#x20;    ตัวอย่างเช่น การเขียนโปรแกรมคำนวณรายได้พนักงานของบริษัทแห่งหนึ่ง ผู้ใช้สามารถเรียกใช้ได้แค่เมดธอด display() ที่ใช้ในการแสดงผลเท่านั้น เนื่องจากเมดธอดที่ใช้ในการคำนวณรายได้เป็นส่วนที่ไม่ได้การให้ถูกเข้าถึง

{% tabs %}
{% tab title="Example code <Abstraction using Classes> C++" %}

```cpp
// oop_p2_3.cpp
#include <iostream>
#include <string>
using namespace std;
class employee{
   int empId;
   string name;
   double salary,basic,allowances;
  
   double calculateSalary(int empId){
   salary = basic+allowances-1000;
   return salary;
}
public:
employee(int empId, string name,double basic,double allowances):
empId(empId),name(name),basic(basic),allowances(allowances){
   calculateSalary(empId);
}
  
void display(){
  
   cout<<"EmpId = "<<empId<<"\tName = "<<name<<endl;
   cout<<"Employee Salary = "<<salary<<endl;
  
}
};
int main()
{
   employee emp(1,"Ved",15000,3245.43);
   emp.display();
   
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Output" %}

```cpp
EmpId = 1       Name = Ved
Employee Salary = 17245.4
```

{% endtab %}
{% endtabs %}

&#x20;

### 2. Abstraction โดยใช้ไฟล์ Header&#x20;

&#x20;    ตัวอย่างเช่น การเรียกใช้งานฟังก์ชัน pow () ที่มีอยู่ใน math.h เมื่อผู้ใช้ต้องการคำนวณเลขยกกำลัง ผู้ใช้สามารถเรียกฟังก์ชัน pow() ที่มีอยู่ใน math.h และส่งตัวเลขเป็นอาร์กิวเมนต์ ฟังก์ชันจะทำการคำนวณผลลัพธ์และส่งผลลัพธ์ออกมาโดยที่ผู้ใช้ไม่ทราบอัลกอริทึมการคำนวณกำลังของตัวเลขภายในฟังก์ชัน

{% tabs %}
{% tab title="Example code <Abstraction using Header file> C++" %}

```cpp
// oop_p2_4.cpp
#include <iostream> 
#include <math.h> 
using namespace std; 

int main() 
{ 
    int x = 6, y = 2; 
  
    int result = pow(x, y); 
    cout << result << endl;
  
    return 0; 
} 
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Output" %}

```cpp
36
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
ความเหมือนระหว่างการใช้งานทั้ง 2 แบบ คือ การให้ข้อมูลที่จำเป็นแก่ภายนอก class ให้รับรู้ว่ามีเมดธอดอะไรที่ควรรู้และสามารถเรียกใช้ได้บ้าง

ความแตกต่างระหว่างการใช้งานทั้ง 2 แบบ คือ

* Abstraction โดยใช้ Class -> ต้องประกาศ class เพื่อเรียกใช้เมดธอดภายใน class นั้น
* Abstraction โดยใช้ไฟล์ Header -> ไม่จำเป็นต้องประกาศ class สามารถเรียกใช้ฟังก์ชันที่มีอยู่ในไฟล์ Header &#x20;
  {% endhint %}

แหล่งที่มาเพิ่มเติม

* <https://www.softwaretestinghelp.com/encapsulation-in-cpp/>
* <https://www.softwaretestinghelp.com/data-abstraction-in-cpp/>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.aic-eec.com/c-c++-for-embedded-programming/object-oriented-programming-oop-in-c++/encapsulation-and-abstraction.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
