840 likes | 1.01k Views
05-530-111 Computer Programming 1. บทที่ 7 การเขียนโปรแกรมเชิงวัตถุ Object-Oriented Programming(OOP). หัวข้อศึกษา. การโปรแกรมแบบเชิงวัตถุ คลาส การกำหนดสิทธิ์ Constructor และ Destructor Static function และ data members Object และ ฟังก์ชัน Object และ อาร์เรย์ Object และ พอยน์เตอร์
E N D
05-530-111 Computer Programming 1 บทที่ 7การเขียนโปรแกรมเชิงวัตถุObject-Oriented Programming(OOP)
หัวข้อศึกษา • การโปรแกรมแบบเชิงวัตถุ • คลาส • การกำหนดสิทธิ์ • Constructor และ Destructor • Static function และ data members • Object และ ฟังก์ชัน • Object และ อาร์เรย์ • Object และ พอยน์เตอร์ • การสืบทอดแบบ Single inheritance • การสืบทอดแบบ Multiple inheritance
โปรแกรมแบบเชิงวัตถุ(Object Oriented Programming) • การแก้ไขปัญหาด้วยวิธี Object-oriented เป็นแนวทางในการแก้ไขปัญหาทางการเขียนโปรแกรมแบบหนึ่งที่แตกต่างจากแบบเดิม ซึ่งมีลักษณะเป็น Structured programming Object Oriented เป็นการเขียนโปรแกรมโดยกำหนดให้ Object ที่ถูกสร้างขึ้นทำงานร่วมกันเพื่อแก้ไขปัญหา • หลักสำคัญ 4 ประการของ Object-oriented คือ • abstraction • encapsulation • modularity • hierarchy
วัตถุ(Object) • เราจะใช้ Object แทนสิ่งต่างๆที่จะใช้ในการแก้ไขปัญหาหรือเขียนโปรแกรม Object สามารถแทนสิ่งต่างๆ ดังนี้ • a physical entity • a concept • a software entity • Object จะประกอบด้วย • attributes • state operations
วัตถุมีสถานะ • สถานะหรือ State ของวัตถุซึ่งสามารถเปรียบได้กับตัวแปร • สถานะของวัตถุจะถูกกำหนดโดยกลุ่มของคุณลักษณะของวัตถุที่เรียกว่า Attribute
วัตถุสามารถให้บริการหรือทำงานวัตถุสามารถให้บริการหรือทำงาน • วัตถุสามารถให้บริการได้ การให้บริการของวัตถุจะถูกกำหนดโดย กลุ่มของ Operation • วัตถุจะให้บริการเมื่อได้รับการร้องขอจากวัตถุ การร้องขอทำได้โดยการส่ง Message
คุณลักษณะสำคัญของ Object Oriented • หลักสำคัญ 4 ประการของ Object Oriented • abstraction • encapsulation • modularity • hierarchy
นามธรรม(Abstraction) • Object oriented ทำให้เราสามารถจำลองระบบโดยการใช้ Abstraction กับปัญหา • Abstraction ทำให้เรามองปัญหาได้หลายระดับ ขึ้นอยู่กับระดับรายละเอียดของปัญหาที่เราสนใจ เช่นเราสามารถซ่อนหรือไม่คิดถึงปัญหาส่วนที่ไม่สำคัญหรือมีความสำคัญน้อย เพื่อลดความซับซ้อนและขนาดของปัญหา • ตัวอย่างเช่น รถเป็นตัวอย่างของ Abstraction ของ สิ่งที่ใช้ในการขนส่งคนจากที่หนึ่งไม่ยังอีกที่หนึ่ง แต่ถ้าเราพูดว่ารถ Toyota สีดำ ปี 2003 รถที่ว่าจะไม่ใช่ Abstraction
การซ่อนรายละเอียด(Encapsulation)การซ่อนรายละเอียด(Encapsulation) • Property และ Operation จะถูกซ่อนและอยู่ภายในObject ถ้าต้องการอ้างถึงหรือใช้งานObject จะต้องทำผ่านทาง Interface • Interface คือ Operationที่ถูกกำหนดไว้เป็นช่องทางสำหรับการสื่อสารระหว่างโลกภายนอกกับObject • Encapsulation ทำให้โปรแกรมง่ายต่อการ Debug และ Maintenance
โมดุล(Modularity) • โมดุลช่วยในการลดความยุ่งยากและซับซ้อนของปัญหาโดยการแบ่งความยุ่งยากซับซ้อนเป็นส่วนเล็กๆ ทำให้ง่ายต่อการจัดการ • โมดุลช่วยในการนำโปรแกรมส่วนนั้นกลับมาใช้ใหม่หรือ Reuse • ตัวอย่างเช่นระบบลงทะเบียน ซึ่งเป็นระบบที่ยุ่งยากและซับซ้อน เราสามารถแบ่งระบบเป็น 3 โมดุลย่อย: ระบบจัดการเกี่ยวกับการเงิน ระบบจัดการเกี่ยวกับการเรียนและวิชาเรียน และระบบจัดการเกี่ยวกับข้อมูลของนักศึกษา และถ้าปัญหายังคงมีความยุ่งยากและซับซ้อน เราก็สามารถแบ่งส่วนปัญหาให้เล็กลงไปอีก
Hierarchy • Hierarchy คือการจัดกลุ่มสิ่งต่างๆตามระดับของ Abstraction โดยการใช้โครงสร้างแบบต้นไม้ (Tree structure) • Hierarchy ช่วยทำให้เราเห็นถึงความเหมือนกันหรือแตกต่างกันของสิ่งต่างๆได้ง่ายขึ้น • Hierarchy ขึ้นอยู่กับมุมมอง(perspective) เช่น เราสามารถแบ่งยานพาหนะเป็นยานพาหนะ ทางอากาศ ทางบก หรือทางเรือ แต่ถ้าเรามองยานพาหนะในแง่ของระบบเครื่องยนต์(เครื่องยนต์เบนซิน ดีเซล หรือ แบบไอน้ำ) เราก็จะได้ Hierarchy ที่แตกต่างกัน
คลาส(Class) • Class คือ Abstraction ที่อธิบายคุณสมบัติของสิ่งต่างๆหรือObject • Class เป็นเครื่องมือที่สำคัญในการเขียนโปรแกรมเชิงวัตถุในภาษา C++ • Class เป็นตัวแปรชนิดหนึ่งที่ภาษา C++ ให้เรากำหนดขึ้น นอกเหนือจากชนิดของตัวแปรที่ภาษา C++ มีให้(Primitive type)เช่น int char หรือ float เป็นต้น ดังนั้นเราจะสร้าง Class ขึ้นเมื่อเราต้องสร้างตัวแปรชนิดใหม่ไว้ใช้ในการเขียนโปรแกรม หรือต้องการเก็บข้อมูลที่มี type แตกต่างกันแต่เกี่ยวข้องกันไว้ด้วยกัน • Class อาจประกอบด้วย Data member กับ Function member เช่น class telephone มี phone numberและ type (tone or rotary) เป็น Data member ไว้เก็บสถานะหรือค่าต่างๆ และมี dial answer hang-up เป็น Function member ไว้ให้บริการหรือทำงาน
คลาส(Class) • โครงสร้างของ Class ประกอบด้วย • Class name • Class data members(attributes) • Class functions (methods/operations) • Class definition เปรียบเสมือน Template สำหรับการสร้าง Object ชนิดนั้นนั้น คล้ายกับการสร้างตัวแปรชนิด int char • Class ทำให้เราสามารถสร้างกลุ่มข้อมูลชนิดใหม่และการดำเนินการกับกลุ่มข้อมูลนั้น
Attribute หรือ Data member • Attribute คือชื่อของคุณสมบัติของClass และAttributeจะเป็นสิ่งที่ใช้ในการเก็บค่าหรือสถานะของObject(instance of class) • Attribute จะมีชนิด(type) ซึ่งทำให้เรารู้ว่าเป็น Attribute ประเภทใด เช่น Attribute ประเภท integer, boolean,หรือ real
Operation หรือ function member • Operation คือบริการที่Classนั้นๆมีไว้ให้Object หรือ Class เรียกใช้ • Operation ใน Class จะเป็นตัวกำหนดว่า Class นั้นสามารถทำอะไรหรือให้บริการอะไรได้บ้าง
Class และ Object • Class member function ในC++ จะเรียกว่า Method • ตัวอย่างการกำหนด (define) Class: class class_name { int data_member;//data member/attributes void show_member(int);//function member/methods }; • หลังการ define เราก็สามารถสร้างตัวแปร(Object)ได้ Class_name object_one, object_two;
Class และ Object • ตัวอย่างการกำหนดหรือสร้าง Employee class: Class Employee { public: char name[64]; long employee_id; float salary; void show_employ(void) { cout<<“name: ”<<name<<endl; cout<<“Id: ”<<employee_id<<endl; cout<<“Salary: “<<salary<<endl; }; };
Class และ Object • การประกาศ Employee worker, boss, secretary; class nameclass variables ( objects ) • ใช้ . (dot operator) ในการให้ค่า(assign) Class data members • ใช้ . (dot operator) ในการเรียก Class member functions • ตัวอย่าง
Class และ Object #include <iostream,h> #include <string.h> class Employee { public: char name[64]; long employee_id; float salary; void show_employ(void) { cout<<“name: ”<<name<<endl; cout<<“Id: ”<<employee_id<<endl; cout<<“Salary: “<<salary<<endl; }; };
Class และ Object void main(void) { Employee worker, boss; strcpy(worker.name, “John Doe”); worker.employee_id=1234; worker.salary=25000; strcpy(boss.name, “Happy Boss”); boss.employee_id=23456; boss.salary=100000; worker.show_employee(); boss.show_employee(); }
Class และ Object • จาก Employee class จะเห็นว่า function ถูกกำหนดไว้ภายใน Class definition ซึ่งถ้า function มีขนาดใหญ่หรือมีหลายๆ function จะทำให้ไม่สะดวกต่อการอ่านหรือศึกษา Class ดังนั้น เราสามารถเขียน Function definition ไว้นอก Class ได้ class Employee { public: char name[64]; long employee_id; float salary; void show_employ(void); }; Function Prototype
Class และ Object Function Name or Method void Employee::show_employ(void) { cout<<“name: ”<<name<<endl; cout<<“Id: ”<<employee_id<<endl; cout<<“Salary: “<<salary<<endl; }; • จากตัวอย่าง ถ้าจะกำหนด Function definition ไว้ภายนอก Class จะต้องใส่ Class name และ Global resolution operator(::) ไว้หน้า Function definition รูปแบบทั่วไปของการกำหนด return _type class_name::function_name(paratmeters){ //statement; } Class name
การกำหนดสิทธิ์ • การกำหนดสิทธิ์ในการอ้างถึงข้อมูล(data members) หรือการเรียกใช้ฟังก์ชัน(method)ใน C++ มี 3 แบบ คือ • private: Data members กับ Methods ที่ถูกประกาศในส่วน private ไม่สามารถเข้าถึงได้จากภายนอกClass ฟังก์ชันที่ประกาศภายใน Class เท่านั้นที่สามารอ้างถึงหรือเรียกใช้ข้อมูลหรือฟังก์ชันในส่วน private ได้ • public:เปิดให้ภายนอก Class ใช้งานได้(เหมือนการเรียกใช้ฟังก์ชันและตัวแปรในบทก่อนๆ) • protected: ฟังก์ชันที่ประกาศภายใน Class และ Sub-class เท่านั้นที่สามารอ้างถึงหรือเรียกใช้ข้อมูลหรือฟังก์ชันในส่วน protected ได้
การกำหนดสิทธิ์ • Information Hiding คือกระบวนการที่ทำให้โปรแกรมสามารถอ้างถึงข้อมูลและเรียกใช้ฟังก์ชันที่จำเป็นเท่านั้น คล้ายกับการที่เราหลีกเลี่ยงการใช้ Global variable. • การกำหนดสิทธิ์(Access specifier)ใช้ private,public หรือ protected ตามด้วย เครื่องหมาย “:” • ตัวอย่างการกำหนด Access specifier class some_class{ public: int some_variable; void initialize_private(int, float); void show_data; private: int key_value; float key_number; }; Public Members Private Members
การกำหนดสิทธิ์ • ตัวอย่างการเรียกใช้ main function: some_class object;//create an object object.some_variable=10;//public data member object.key_value=10;//wrong private data member //syntax errors object.initialize_private(20, 12.345);//call public method object.show_data(); );//call public method • โดยทั่วไปเราจะไม่อนุญาติให้โปรแกรมสามารถอ้างถึง data member ได้โดยตรง โปรแกรมควรจะอ้างถึง Data member ผ่าน Public method(interface)
class main() object1 object2 OK private private OK OK public public
การกำหนดสิทธิ์ • ตัวอย่าง #include<iostream.h> #include<string.h> class employee{ public: int assign_values(char* arg_name, long arg_employee_id, float arg_salary); void show_employee(void); int change_salary(float); long get_id(void); private: char name[64]; long employee_id; float salary; };
การกำหนดสิทธิ์ int employee::assign_values(char* emp_name, long emp_id, float emp_salary){ strcpy(name, emp_name); employee_id=emp_id; if( emp_salary<50000.0){ salary=emp_salary; return (0);//sucessful; else { return (-1);//invalid salary } }
การกำหนดสิทธิ์ void employee::show_employee(void){ cout<< “Employee: “<<name<<endl; cout<< “Id: “ <<employee_id<<endl; cout<< “Salary: “ <<salary<<endl; } int employee::change_salary(float new_salary){ if( new_salary<50000.0){ salary=new_salary; return (0); }else { return (-1); } }
long employee::get_id(void){ return (employee_id); } int main(void){ employee worker; if( worker.assign_values(“Jim Fish”,101,10101.0)==0){ cout<< “Employee values assigned” <<endl; worker.show_employee(); if( worker.change_salary(35000.0)==0){ cout<< “New salary assigned” <<endl; worker.show_employee(); }else { cout<< “Invalid salary specified” <<endl; } return 0; }
การกำหนดสิทธิ์ • การใช้ “::” (global resolution operator) ก็เพื่อป้องกันการซ้ำกันของชื่อฟังก์ชัน • Method ไม่จำเป็นต้องประกาศเป็น public access เสมอไป • C++ กำหนดให้(default) data member และ method เป็น private
Constructor และ Destructor • Constructor เป็น Class method ที่มีชี่อเหมือนกับ Classและจะถูกเรียกอัตโนมัติเมื่อมีการสร้าง Object • เรามักจะใช้ Constructor ในการกำหนดค่าเริ่มต้นให้กับ Data members • ถ้าเราไม่กำหนดหรือเขียนConstructor Compilerจะให้Constructor ที่เรียกว่า Default constructor • ตัวอย่างการสร้าง Constructor สำหรับ Class employee
Constructor และ Destructor class employee{ public: employee(char*, long, float);//constructor (no return type) void show_employee(void); int change_salary(float); long get_id(void); private: char name[64]; long employee_id; float salary; };
Constructor และ Destructor employee::employee(char* name,long employee_id,float salary) { strcpy(employee::name, name); employee::employee_id= employee_id; if( salary<50000){ employee::salary=salary; }else{ employee::salary=0.0;//invalid salary specified } }
Constructor และ Destructor void employee::show_employee(void){ cout<< “Employee: “<<name<<endl; cout<< “Id: “<<employee_id<<endl; cout<< “Salary: “<<salary<<endl; } int main(void){ employee worker(“Jim Jones”, 101,10000.0);//constructor //ถูกเรียก worker.show_employee(); }
Constructor และ Destructor • จะเห็นได้ว่า Constructor ไม่มีการ return ค่าและไม่ต้องใส่ void ไว้หน้า Constructor • การสร้าง Object ของ Class employee ชื่อ worker พร้อม initial ค่าให้แก่ Data members: name, employee_id และ salary • Constructor ของ Class employee ถูกเรียกอัตโนมัติ
Constructor และ Destructor • การ Overloading constructor คือการที่เราสร้าง Constructor หลายอันโดยกำหนดให้ Constuctorแต่ละอัน มี Parameter แตกต่างกันเช่น 1.employee(char*, long, float); 2.employee(char*, long); ถ้ามีการเรียกสร้าง Object : employee worker(“Jim Jones”, 101,10000.0); Constructor หมายเลข 1 จะถูกเรียก employee worker(“Jim Jones”, 101); Constructor หมายเลข 2 จะถูกเรียก
Constructor และ Destructor • Destructor function จะมีไว้สำหรับการทำลาย(free up/clean)Object และจะถูกเรียกโดยอัตโนมัติเมื่อมีการทำลาย Object • Desctructor function จะมีชื่อเหมือน Class แต่มีเครื่องหมาย ~(tilde) นำหน้า • ตัวอย่าง Destructor ~class_name(void){ //function statement }
Constructor และ Destructor employee::~employee(void){ cout<< “Destroying the object for” <<name<<endl; } • เมื่อ run โปรแกรมตอนจบ(ออกจาก main function) Destructor จะถูกเรียก • โดยทั่วไปถ้าไม่มีการ Dynamic allocate memory ใน Object ก็ไม่ต้องมี Code เพื่อปลดปล่อย(release) Memory
Static function และ data members • โดยปกติเมื่อสร้างObject Objectแต่ละตัวที่ถูกสร้างขึ้นก็จะมีค่าหรือสถานะเก็บใน Data member(s) เป็นของตัวเอง ในบางครั้งถ้าเราต้องการให้มีการใช้ค่าร่วมกัน(share)ในระหว่าง Object เราสามารถทำได้โดยการเพิ่มคำว่า static ไว้หน้า type ของ Data member ตัวอย่างเช่น private: static int shared_valued; • และเมื่อต้องการอ้างถึง สามารถทำได้โดย int class_name::shared_valued
Static function และ data members • ตัวอย่าง class book_series{ public: book_series(char*, char*, float); void show_book(void); void set_page(int); private: static int page_count; char title[64]; char author[64]; float price; };
Static function และ data members int book_series::page_count; void book_series::set_pages(int pages){ page_count=pages; } book_series::book_series(char* title,char* author, float price){ strcpy(book_series::title, title); strcpy(book_series::author, title); book_series::price=price; }
Static function และ data members void book_series::show_book(void){ cout<< “Title: “<<title<<endl; cout<< “Author: “<<author<<endl; cout<< “Price: “<<price<<endl; cout<< “Pages: “<<page_count<<endl; }
Static function และ data members int main(void){ book_series programming(“C++ How to”,”D&D”,20.0); book_series word(“Word for window”,”Ant”,10.0); word.set_pages(256); programming.show_book(); word.show_book(); cout<<endl<< “Change page count ” <<endl; programming.set_pages(500); programming.show_book(); word.show_book(); return 0; }
Static function และ data members • จะเห็นได้ว่าเมื่อประกาศให้ page_count เป็น static int โปรแกรมจะทำให้ page_count member เป็นเสมือน Global variable เมื่อโปรแกรมเปลี่ยนค่าของ page_countobjectทุกตัวจะเห็นค่าที่เปลี่ยน • การประกาศ Data member หรือ Method เป็น static ทำให้เราสามารถเรียกใช้ Method หรือ initial ค่าโดยไม่ต้องสร้าง Object เนื่องจากการประกาศ Member แบบ static เปรียบเสมือนการประกาศ Member ให้กับ Class ไม่ใช่ให้กับ Object