This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
tutorial:oop [2018/12/25 15:45] admin |
tutorial:oop [2019/01/17 07:33] admin |
||
---|---|---|---|
Line 9: | Line 9: | ||
=====OOP มีอะไรบ้าง===== | =====OOP มีอะไรบ้าง===== | ||
- | โดยทั่วไป หลักการ OOP ในหลายๆภาษาจะคล้ายคลึงกัน แตกต่างกันเพียงแค่ Syntax เท่านั้น โดยหลักการดังกล่าว มักจะประกอบไปด้วยส่วนต่างๆดังต่อไปนี้ | + | โดยทั่วไป หลักการ OOP ในหลายๆภาษาจะคล้ายคลึงกัน โดยหลักการดังกล่าวได้ถูกหล่อหลอมรวมกันจนกลายมาเป็น Class และ Object นั่นเอง อธิบายได้แบบสั้นๆง่ายๆดังนี้ (เนื่องจาก Class และ Object คล้ายกัน เนื่องจากเกิดมาจากหลักการ OOP เหมือนกัน ดังนั้นจะขอนำแค่ Class มายกตัวอย่าง) |
- | ====2. Encapsulation==== | + | ====1. Encapsulation==== |
- | ====3. Inheritance==== | + | คือ การจำกัดการเข้าถึง Field, Method และ Property ต่างๆ ของ Class นั้นๆ เพื่อไม่ให้เกิดการเรียกใช้งานจากภายนอกอย่างไม่เหมาะสม การจำกัดการเข้าถึงในที่นี้คือการใส่ Access Specifier เหล่านี้ คือ Private, Protected, Public และ Published สำหรับรายละเอียดสามารถอ่านได้จากหัวข้อถัดไป |
- | ====4. Polymorphism==== | + | ====2. Inheritance==== |
- | ====5. Overriding==== | + | คือ การถ่ายทอด สืบต่อ เช่น Class B สืบต่อความสามารถมาจาก Class A จะทำให้ Class B สามารถทำทุกอย่างที่ Class A ทำได้ |
- | ====6. Overloading==== | + | ====3. Polymorphism==== |
- | + | คือ การเปลี่ยนรูปร่าง เช่น หาก Class B สืบต่อความสามารถมาจาก Class A จะทำให้ Class B ถูกมองว่าเป็น Class B หรือ Class A ก็ได้ในขณะเดียวกัน | |
- | =====1. Classes and Instances===== | + | ====4. Overriding==== |
- | หากเราจำเป็นต้องสร้างโค๊ดเกี่ยวกับอะไรสักอย่างหนึ่ง ยกตัวอย่าง เช่น รถยนต์ โดยที่รถยนต์ที่เราจะสร้างขึ้นมานั้น มีหลายคัน คงจะลำบากไม่ใช่น้อยที่จะต้องมาเขียนโค๊ดสำหรับรถยนต์เหล่านั้นไปทีละตัวจนหมด ปัญหาเหล่านี้จะหมดไป หากเรารู้จักการเขียน Class และ Object(Instance) \\ \\ | + | คือ การปรับเปลี่ยน เช่น หาก Class B สืบต่อความสามารถมาจาก Class A แล้ว สำหรับ Class B เราสามารถปรับเปลี่ยนความสามารถที่ได้รับมาจาก Class A เพื่อให้ทำงานได้เหมาะสมขึ้น |
- | + | ||
- | **Classes** คือ ต้นแบบ เปรียบเสมือนการออกแบบรถยนต์ว่าควรประกอบไปด้วยคุณสมบัติอะไรบ้าง เช่น โครงสร้าง เครื่องยนต์ ช่วงล่าง ระบบส่งกำลัง ตัวถัง เป็นต้น ทั้งหมดที่กล่าวมานี้ เราเรียกว่า Property แค่นั้นยังไม่พอ รถยนต์ควรจะมีความสามารถอะไรบ้าง นั่นคือ ขับได้ วิ่งไปมาด้วยความรวดเร็วได้ เบรคได้ เราเรียกสิ่งนี้ว่า Method | + | |
- | + | ||
- | **Objects (Instances)** คือ ผลิตภัณท์ที่เกิดจากต้นแบบ (Class) เช่น เราผลิตรถยนต์ขึ้นมาใช้งานจริง 5 คัน ซึ่งใน 5 คันนี้ อาจมี Property ที่ต่างกันไป แต่ทุกคันมี Method ที่เหมือนกัน เราเรียกรถยนต์เหล่านี้ว่า Object หรือ Instance เป็นต้น แต่เนื่องจากคำว่า Object มีใช้ในภาษา Pascal เช่นกัน และเป็นคำเฉพาะซึ่งหมายถึงการสร้างวัตถุที่เป็นต้นแบบขึ้นมาเหมือนกัน (คล้าย Class) ดังนั้นต่อไปนี้จะขอใช้คำว่า Instance แทน | + | |
- | + | ||
- | **__หมายเหตุ__** - **Object** สำหรับภาษา Pascal หมายถึงการสร้างวัตถุที่มีทั้งคุณสมบัติ (Property) และกระบวนการ (method) เหมือนกันกับ Class เพียงแต่ Class นั้นเพิ่งเกิดมาในภายหลัง โดย Object จะคล้ายกับ Record ที่มี Property กับ Method นั่นเอง หรือ ที่เรียกว่า Advance Record \\ | + | |
- | ในโปรแกรม Turbo Pascal สมัยก่อน Object ถูกใช้ทำหน้าที่เหมือนกันกับ Class แต่ต่อมาภายหลัง เมื่อมีการเปิดตัว Delphi จึงได้มีการคิดค้น Class ขึ้นมาเพื่อใช้งานแทน Object แต่อย่างไรก็ตาม Object ก็ยังเป็นที่นิยมใช้กันมาปกติจนถึงปัจจุบัน | + | |
- | สิ่งที่แตกต่างกัน ระหว่าง Class กับ Object คือ | + | |
- | *Object ใช้หน่วยความจำแบบ Stack ส่วน Class ใช้หน่วยความจำแบบ Heave นั่นทำให้ทุกครั้งที่มีการสร้าง Instance จาก Class ขึ้นมาใช้งาน จำเป็นต้องมีการกำจัด Instance เมื่อใช้งานเสร็จเสมอ เพื่อไม่ให้เกิดปัญหา Memory Leak | + | |
- | *Object ใช้การอ้างอิงตัวแปรแบบ Value ส่วน Class ใช้การอ้างอิงตัวแปรแบบ Reference เพื่อให้เห็นภาพ ขอยกตัวอย่าง หากให้ A,B เป็น Object เมื่อใช้คำสั่ง B:=A ; จะหมายถึง มี B เกิดขึ้นมาอีกหนึ่งตัวซึ่งเกิดจากการคัดลอก A ผลก็คือหากเราทำอะไรกับ B ก็จะไม่ส่งผลกับ A เพราะเป็นคนละตัวกัน แต่หากเราให้ A,B เป็น Instance ของ Class เมื่อใช้คำสั่ง B:=A ; จะกลายเป็นว่า B อ้างอิงไปที่ A ไม่ได้เกิดการคัดลอกใดๆ ทีนี้หากเราทำการเปลี่ยนแปลง B จะหมายถึงการเปลี่ยนแปลง A ด้วยเช่นกัน | + | |
- | + | ||
- | การสร้าง Class เริ่มต้น ทำได้ดังนี้ | + | |
- | + | ||
- | Type | + | |
- | TMyClass = class | + | |
- | Item:integer; | + | |
- | Procedure DoSomething; | + | |
- | end; | + | |
- | + | ||
- | การสร้าง Class ต่อจาก Class อื่น หรือเรียกว่าการสืบทอด (Inheritance) ทำได้ดังนี้ | + | |
- | + | ||
- | Type | + | |
- | TMyClass = class(TBaseClass) | + | |
- | Item:integer; | + | |
- | Procedure DoSomething; | + | |
- | end; | + | |
- | + | ||
- | องค์ประกอบของ Class แบบละเอียด มีดังนี้ | + | |
- | + | ||
- | <sxh delphi;> | + | |
- | Type | + | |
- | TMyItem = class(TPersistent); | + | |
- | private | + | |
- | FName:string; | + | |
- | FValue:integer; | + | |
- | function GetIsOK:boolean; | + | |
- | protected | + | |
- | procedure DoSomeThing1; | + | |
- | procedure DoSomeThing2; virtual; | + | |
- | public | + | |
- | constructor Create; override; | + | |
- | destructor Destroy; override; | + | |
- | procedure Assign(Source: TPersistent); override; | + | |
- | property IsOK:boolean read GetIsOK; | + | |
- | property ValueX:integer read GetValueX write SetValueX; | + | |
- | published | + | |
- | property Name:string read FName write FName; | + | |
- | property Value:integer read FValue write FValue default 0; | + | |
- | </sxh> | + | |
- | + | ||
- | **Ancestor Class** หรือ **Super Class** คือ class ต้นแบบ จากตัวอย่าง คือ TPersistent | + | |
- | \\ \\ | + | |
- | **Field Parameters** คือ ส่วนที่ถูกประกาศเป็นตัวแปรคล้ายกับการประกาศ var จากตัวอย่างข้างบน คือ FName และ FValue ตัวแปรเหล่านี้มักถูกประกาศเพื่อใช้เก็บค่าสำหรับ Property | + | |
- | \\ \\ | + | |
- | ==== Constructor and Destructor ==== | + | |
- | คือ Procedure ชนิดหนึ่ง แต่มีความสำคัญต่อ class มาก จึงต้องเขียนให้มีชื่อเฉพาะเป็นของตนเอง Constructor จะที่ถูกเรียกเพื่อใช้สร้าง Instance โดยทำการจัดสรรหน่วยความจำให้เหมาะสม ส่วน Destructor จะถูกเรียกเพื่อทำลาย Instance แล้วคืนหน่วยความจำ\\ \\ | + | |
- | ====Properties==== | + | |
- | คือคุณสมบัติของ Instance ประกอบไปด้วย Getter (คำสั่งหลัง read) และ Setter (คำสั่งหลัง write)\\ \\ | + | |
- | เพื่อเป็นการอธิบายให้เห็นภาพ จะขอยกตัวอย่าง | + | |
- | + | ||
- | property ValueX:integer read GetValueX write SetValueX; | + | |
- | + | ||
- | จากตัวอย่างดังกล่าว Getter คือ GetValueX ส่วน Setter คือ SetValueX \\ | + | |
- | Getter จะถูกเรียกใช้งาน เมื่อมีการเรียกต่าจาก Property ดังเช่น | + | |
- | + | ||
- | writeln(ValueX); | + | |
- | + | ||
- | Setter จะถูกเรียกใช้งาน เมื่อมีการ Assign ค่าใส่ Property เช่น | + | |
- | + | ||
- | ValueX:=12; | + | |
- | + | ||
- | ทำไมต้องมี Getter Setter ให้ยุ่งยาก แทนที่จะใช้ var อย่างเดียว? ประโยชน์ของมันมีดังนี้ครับ | + | |
- | *ใช้คัดกรองตัวแปร บางครั้งเรารับค่าเพื่อการคำนวณในช่วง 0-100 เท่านั้น หากผู้ใช้ใส่ค่าเกินกว่าค่าดังกล่าวมา จะสามารถคัดกรองให้เป็นค่าที่อยู่ในช่วง 0-100 แทนได้ | + | |
- | *เพื่อให้ค่าของ Property ได้มีการ update ตลอดเวลา โดยเฉพาะหาก property ของเรา ขึ้นอยู่กับค่าอื่น เมื่อใดที่มีการเปลี่ยนค่า ก็จะมีการ update ค่า property เราด้วยเสมอ\\ | + | |
- | + | ||
- | รูปแบบการเขียน Property มีหลักๆดังนี้ | + | |
- | *Property ที่มี Getter, Setter เป็น Field | + | |
- | + | ||
- | property Value:integer read FValue write Value; | + | |
- | + | ||
- | *property ที่มี Getter, Setter เป็น Procedure/Function ซึ่งโดยปกติ Getter จะเป็น Function ส่วน Setter จะเป็น Procedure | + | |
- | + | ||
- | property ValueX:integer read GetValueX write SetValueX; | + | |
- | function GetValueX:integer; | + | |
- | procedure SetValueX(Value:integer); | + | |
- | + | ||
- | *Property ที่แสดงค่าได้อย่างเดียว (ReadOnly) | + | |
- | + | ||
- | property IsOK:boolean read GetIsOK; | + | |
- | + | ||
- | \\ \\ | + | |
- | + | ||
- | ====Access Modifiers==== | + | |
- | คือ private, protected, public และ published โดยแต่ละตัวกำหนดความสามรถในการเข้าถึง Field, Procedure, Function หรือ Property ที่อยู่ภายใต้ สรุปได้ดังนี้ | + | |
- | + | ||
- | ^ Access Modifier ^ Descriptions ^ | + | |
- | |private| มองเห็นได้เฉพาะที่อยู่ใน Unit เดียวกันกับ Class นี้เท่านั้น | | + | |
- | |protect| มองเห็นได้เฉพาะ Derived-Class เท่านั้น | | + | |
- | |public| มองเห็นได้จากทุกที่ที่ uses Unit นี้ | | + | |
- | |published| เหมือนกันกับ Public แต่จะสร้าง Run Time Type Information (RTTI) ด้วย | | + | |