This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
tutorial:class [2019/01/28 09:39] admin |
tutorial:class [2019/01/29 08:24] admin |
||
---|---|---|---|
Line 2: | Line 2: | ||
คือ Structural Type ชนิดหนึ่ง ซึ่งมีทั้ง Field, Method และ Property เหมือนกับ Object แต่มีรายละเอียดที่ซับซ้อนมากกว่า \\ | คือ Structural Type ชนิดหนึ่ง ซึ่งมีทั้ง Field, Method และ Property เหมือนกับ Object แต่มีรายละเอียดที่ซับซ้อนมากกว่า \\ | ||
- | คำว่า Class จริงๆแล้วนั้น หมายถึง ต้นแบบ ซึ่งหากจะนำไปใช้จริงๆ จะต้องสร้างตัวผลิตภัณท์ของ Class นั้นขึ้นมา ในมี่นี้ เราเรียกว่า Instance \\ | + | คำว่า Class จริงๆแล้วนั้น หมายถึง ต้นแบบ ซึ่งในการนำไปใช้งานจริงนั้น จำเป็นต้องสร้างตัวผลิตภัณท์ของ Class นั้นขึ้นมาอีกที ในที่นี้ เราเรียกว่า Instance \\ |
เพื่อให้เห็นภาพ ขอยกตัวอย่างเรื่องการสร้างรถยนต์ Class ในที่นี้ เปรียบเสมือน"พิมพ์เขียว"ของรถยนต์ ส่วน Instance คือ รถยนต์จริงๆที่ถูกผลิตขึ้นโดยใช้พิมพ์เขียวดังกล่าว ซึ่งแน่นอนว่ารถยนต์เหล่านี้ ย่อมมีคุณสมบัติแตกต่างกัน เช่น สีรถ เครื่องยนต์ หรืออุปกรณ์มาตรฐานต่างๆ เป็นต้น \\ | เพื่อให้เห็นภาพ ขอยกตัวอย่างเรื่องการสร้างรถยนต์ Class ในที่นี้ เปรียบเสมือน"พิมพ์เขียว"ของรถยนต์ ส่วน Instance คือ รถยนต์จริงๆที่ถูกผลิตขึ้นโดยใช้พิมพ์เขียวดังกล่าว ซึ่งแน่นอนว่ารถยนต์เหล่านี้ ย่อมมีคุณสมบัติแตกต่างกัน เช่น สีรถ เครื่องยนต์ หรืออุปกรณ์มาตรฐานต่างๆ เป็นต้น \\ | ||
Line 11: | Line 11: | ||
*Object ใช้หน่วยความจำแบบ Stack ส่วน Class ใช้หน่วยความจำแบบ Heave นั่นทำให้ทุกครั้งที่มีการสร้าง Instance จาก Class ขึ้นมาใช้งาน จำเป็นต้องมีการกำจัด Instance เมื่อใช้งานเสร็จเสมอ เพื่อไม่ให้เกิดปัญหา Memory Leak | *Object ใช้หน่วยความจำแบบ Stack ส่วน Class ใช้หน่วยความจำแบบ Heave นั่นทำให้ทุกครั้งที่มีการสร้าง Instance จาก Class ขึ้นมาใช้งาน จำเป็นต้องมีการกำจัด Instance เมื่อใช้งานเสร็จเสมอ เพื่อไม่ให้เกิดปัญหา Memory Leak | ||
*Class จำเป็นต้องมี Constructor และ Destructor เสมอ ซึ่งสองตัวนี้ คือ Procedure พิเศษ มีไว้สำหรับสร้างและทำลาย Instance ตามลำดับ ในขณะที่ Object ไม่จำเป็นต้องมี | *Class จำเป็นต้องมี Constructor และ Destructor เสมอ ซึ่งสองตัวนี้ คือ Procedure พิเศษ มีไว้สำหรับสร้างและทำลาย Instance ตามลำดับ ในขณะที่ Object ไม่จำเป็นต้องมี | ||
- | *Object ใช้การอ้างอิงตัวแปรแบบ Value ส่วน Class ใช้การอ้างอิงตัวแปร สาเหตุที่เป็นแบบนี้ ให้ดูหัวข้อถัดไปแบบ Reference เพื่อให้เห็นภาพ ขอยกตัวอย่าง หากให้ A,B เป็น Object เมื่อใช้คำสั่ง B:=A ; จะหมายถึง มี B เกิดขึ้นมาอีกหนึ่งตัวซึ่งเกิดจากการคัดลอก A ผลก็คือหากเราทำอะไรกับ B ก็จะไม่ส่งผลกับ A เพราะเป็นคนละตัวกัน แต่หากเราให้ A,B เป็น Instance ของ Class เมื่อใช้คำสั่ง B:=A ; จะกลายเป็นว่า B อ้างอิงไปที่ A ไม่ได้เกิดการคัดลอกใดๆ ทีนี้หากเราทำการเปลี่ยนแปลง B จะหมายถึงการเปลี่ยนแปลง A ด้วยเช่นกัน | + | *Object ใช้การอ้างอิงตัวแปรแบบ Value ส่วน Class ใช้การอ้างอิงตัวแปรแบบ Reference เพื่อให้เห็นภาพ ขอยกตัวอย่าง หากให้ A,B เป็น Object เมื่อใช้คำสั่ง B:=A ; จะหมายถึง มี B เกิดขึ้นมาอีกหนึ่งตัวซึ่งเกิดจากการคัดลอก A ผลก็คือหากเราทำอะไรกับ B ก็จะไม่ส่งผลกับ A เพราะเป็นคนละตัวกัน แต่หากเราให้ A,B เป็น Instance ของ Class เมื่อใช้คำสั่ง B:=A ; จะกลายเป็นว่า B อ้างอิงไปที่ A ไม่ได้เกิดการคัดลอกใดๆ ทีนี้หากเราทำการเปลี่ยนแปลง B จะหมายถึงการเปลี่ยนแปลง A ด้วยเช่นกัน |
*Class มี Access Modifier เพิ่มขึ้นมาจาก Object ซึ่งมีรายละเอียดดังนี้ | *Class มี Access Modifier เพิ่มขึ้นมาจาก Object ซึ่งมีรายละเอียดดังนี้ | ||
Line 21: | Line 21: | ||
|ไม่ระบุ| หมายถึง public | | |ไม่ระบุ| หมายถึง public | | ||
+ | \\ | ||
+ | ---- | ||
+ | =====การสร้าง Class===== | ||
+ | การสร้าง Class อย่างง่าย มีรูปแบบดังนี้ | ||
+ | Type | ||
+ | TMyClass = class | ||
+ | {Field, Method, Property...} | ||
+ | end; | ||
+ | |||
+ | การสร้าง Class สืบทอดจาก Class อื่น มีรูปแบบดังนี้ () | ||
+ | |||
+ | Type | ||
+ | TMyClass = class(TObject) | ||
+ | {Field, Method, Property...} | ||
+ | end; | ||
+ | |||
+ | __**หมายเหตุ**__ - ในการสร้าง Class ทุกๆครั้งที่ไม่ได้ระบุว่าสืบทอดมาจาก Class ใด จะเป็นการสร้าง Class สืบทอดจาก TObject ซึ่งเป็น Class พื้นฐานของ FPC เสมอ \\ | ||
+ | |||
+ | ตัวอย่างการสร้าง Class แบบละเอียด | ||
+ | <sxh delphi;> | ||
+ | Type | ||
+ | TMyClass = class(TObject) | ||
+ | private | ||
+ | FName:string; | ||
+ | FValue:integer; | ||
+ | protected | ||
+ | function GetIsOK:boolean; | ||
+ | public | ||
+ | constructor create; | ||
+ | destructor destroy; override; | ||
+ | procedure DoSomeThing; | ||
+ | published | ||
+ | property Name:string read FName write FName; | ||
+ | property Value:integer read FValue write FValue default 0; | ||
+ | property IsOK:boolean read GetIsOK; | ||
+ | end; | ||
+ | </sxh> | ||
+ | \\ | ||
+ | |||
+ | ---- | ||
+ | =====Property===== | ||
+ | คือ คุณสมบัติของ Class (หรือ Object) เช่น ความยาว ความกว้าง ตำแหน่ง เป็นต้น โครงสร้างของ property นั้นประกอบไปด้วย Getter (คำสั่งหลัง read) และ Setter (คำสั่งหลัง write)\\ \\ | ||
+ | เพื่อเป็นการอธิบายให้เห็นภาพ จะขอยกตัวอย่าง | ||
+ | |||
+ | property ValueX:integer read GetValueX write SetValueX; | ||
+ | |||
+ | จากตัวอย่างดังกล่าว Getter คือ GetValueX ส่วน Setter คือ SetValueX \\ | ||
+ | Getter จะถูกเรียกใช้งาน เมื่อมีการเรียกใช้ค่าของ Property ดังเช่น | ||
+ | |||
+ | writeln(ValueX); | ||
+ | | ||
+ | Setter จะถูกเรียกใช้งาน เมื่อมีการใส่ค่าให้ Property เช่น | ||
+ | |||
+ | ValueX:=12; | ||
+ | | ||
+ | ทำไมต้องมี Getter Setter ให้ยุ่งยาก แทนที่จะใช้ var หรือ Field อย่างเดียว? ประโยชน์ของการใช้งาน Property มีดังนี้ครับ | ||
+ | *ใช้คัดกรองตัวแปร บางครั้งเรารับค่าเพื่อการคำนวณในช่วง 0-100 เท่านั้น หากผู้ใช้ใส่ค่าเกินกว่าค่าดังกล่าวมา จะสามารถคัดกรองให้เป็นค่าที่อยู่ในช่วง 0-100 แทนได้ | ||
+ | *เพื่อให้ค่าของ Property ได้มีการ update ตลอดเวลา โดยเฉพาะหาก property ของเรา ขึ้นอยู่กับค่าอื่น เมื่อใดที่มีการเปลี่ยนค่า ก็จะมีการ update ค่า property เราด้วยเสมอ | ||
+ | |||
+ | |||
+ | รูปแบบการเขียน Property มีหลักๆดังนี้ | ||
+ | *Property ที่มี Getter, Setter เป็น Field | ||
+ | |||
+ | property Value:integer read FValue write FValue; | ||
+ | |||
+ | *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; |