User Tools

Site Tools


Sidebar


Introduction


Basic Tutorials


Advance Tutorials


Useful Techniques


Examples

  • Simple Pipe Weight Calculator
  • Unit Convertor

Sidebar

tutorial:record

This is an old revision of the document!


Record and Object


Record

คือ Data Type ชนิดหนึ่ง เรียกว่า Structural Type เป็นตัวแปรที่เก็บข้อมูลได้หลายประเภท ซึ่งแตกต่างจาก Array ที่สามารถเก็บข้อมูลได้แค่ประเภทเดียวกัน รูปแบบการประกาศ Record มีดังนี้

Type
   TMyRec = record
     Name:string;
     Value: integer;     
   end;

จากการประกาศข้างบน เราได้สร้าง Data Type ที่ชื่อว่า TMyRec ขึ้นมา ซึ่งเป็น Record

Example-1: Record

Example-1: Record

program Simple_Record;

type
  TMyRec =  record
    Name:string;
    Value:integer;
    Arr:array[1..3] of real;
  end;

var
  MyRec1: TMyRec;

begin
  MyRec1.Name:='MyRec1';
  MyRec1.Value:=1;
  MyRec1.Arr[1]:=1.234;
  MyRec1.Arr[2]:=5.123;
  MyRec1.Arr[3]:=7.890;

  writeln('MyRec1.Name = ',MyRec1.Name);
  writeln('MyRec1.Value = ',MyRec1.Value);
  writeln('MyRec1.Arr[1] = ',MyRec1.Arr[1]);
  writeln('MyRec1.Arr[2] = ',MyRec1.Arr[2]);
  writeln('MyRec1.Arr[3] = ',MyRec1.Arr[3]);
  readln();
end.  

Compiled Results:

MyRec1.Name = MyRec1
MyRec1.Value = 1
MyRec1.Arr[1] =  1.2340000000000000E+000
MyRec1.Arr[2] =  5.1230000000000002E+000
MyRec1.Arr[3] =  7.8899999999999997E+000    



Advanced Record

ปกติแล้ว Record จะมีแค่ Field Variable อยู่ภายใน แต่ยังมี Record อีกประเภทหนึ่งที่มี Method และ Property ได้ เรียกว่า Advanced Record

Advanced Record ถูกสร้างขึ้นเพื่อให้มีความสามารถทางด้าน Object Oriented Programming เช่นเดียวกับ Object จะเรียกได้ว่า Advanced Record กับ Object นั้นเหมือนกันแทบทั้งหมดก็ว่าได้

การประกาศ Advanced Record จำเป็นต้องมี Compiler Directive ต่อไปนี้

{$modeSwitch advancedRecords}

จากนั้น เราก็สามารถประกาศ Record ให้มีหน้าตาคล้ายกับ Object ได้แบบนี้

Type
   TMyRec = record
     FName:string;
     FValue: integer;
     Procedure DoSomething;  
     Function GetSomething:integer;    
   end;

Example-2: Advanced Record

Example-2: Advanced Record

program Advanced_Record;
{$modeSwitch advancedRecords}

type

  { TMyRec }

  TMyRec =  record
    Name:string;
    Value:integer;
    Arr:array[1..3] of real;

    procedure ShowData;
    function GetValue:integer;
  end;

var
  MyRec1: TMyRec;

{ TMyRec }

procedure TMyRec.ShowData;
begin
  writeln('Name = ',Name);
  writeln('Value = ',Value);
  writeln('Arr[1] = ',Arr[1]);
  writeln('Arr[2] = ',Arr[2]);
  writeln('Arr[3] = ',Arr[3]);
end;

function TMyRec.GetValue: integer;
begin
  result:=Value*100;
end;

begin
  MyRec1.Name:='MyRec1';
  MyRec1.Value:=1;
  MyRec1.Arr[1]:=1.234;
  MyRec1.Arr[2]:=5.123;
  MyRec1.Arr[3]:=7.890;

  MyRec1.ShowData;
  writeln('MyRec.GetValue = ',MyRec1.GetValue);

  readln();
end.   

Compiled Results:

Name = MyRec1
Value = 1
Arr[1] =  1.2340000000000000E+000
Arr[2] =  5.1230000000000002E+000
Arr[3] =  7.8899999999999997E+000
MyRec.GetValue = 100   




Object

ถูกสร้างขึ้นมาตั้งแต่สมัยที่ยังใช้ Turbo Pascal โดยออกแบบให้เป็นไปตามหลักการ Object Oriented Programming (OOP) ลักษณะการใช้งานโดยทั่วไปจะคล้ายกับ Advanced Record

สาเหตุที่มีให้ใช้ทั้ง Object และ Advanced Record นั้น เพราะว่าภายหลังจากที่ Delphi เปิดตัว ได้มีการนำ Class มาใช้แทน Object และผลักดันให้ เรียก Object ว่าเป็น Advanced Record แทน (อันนี้ผมเข้าใจว่า เพราะคำว่าว่า Object ในภาษาทั่วไป คือ instance ซึ่งแปลว่าผลิตภัณท์ที่เกิดจากต้นแบบ (Class) ซึ่งอาจสร้างความสับสนให้ผู้ใช้ได้) ทีนี้ทางฝั่งของ FPC ซึ่งมีการออกแบบให้โค๊ดทั้งหลายคล้ายคลึงกับทั้งทาง Turbo Pascal และ Delphi อยู่แล้วนั้น ได้ตัดสินใจเก็บ Object ไว้ เพื่อให้ยัง Compatible กับ Turbo Pascal อยู่นั่นเอง แต่ถึงอย่างไรทั้งสอง ก็ถูกใช้งานเหมือนกัน

การประกาศ Object อย่างง่าย ทำได้ดังนี้

Type
   TMyRec = object
     FName:string;
     FValue: integer;
     Procedure DoSomething;  
     Function GetSomething:integer;    
   end;

อย่างไรก็ตาม ในการนำ Object ใช้งานจริงนั้น ไม่ได้มีเพียงแค่ Field กับ Method ดังที่เห็นในตัวอย่าง แต่ยังมีส่วนประกอบอื่นๆอีกมากมาย อาทิเช่น Property, Access Specifiers เป็นต้น

ตัวอย่างการสร้าง Object แบบละเอียด

Type
  TMyItem = object
   private
     FName:string;
     FValue:integer; 
     function GetIsOK:boolean;  
   public
     procedure DoSomeThing;
     property Name:string read FName write FName;
     property Value:integer read FValue write FValue default 0;
     property IsOK:boolean read GetIsOK; 
   end;


จากตัวอย่างโค๊ดข้างบน จะอธิบายส่วนประกอบต่างๆทีละส่วนดังนี้

Access Specifiers

type
  TObj = object
    private
      { private declarations }
    public
      { public declarations }
  end;

คือ private และ public โดยแต่ละตัวกำหนดความสามรถในการเข้าถึง Field, Procedure, Function หรือ Property ที่อยู่ภายใต้ สรุปได้ดังนี้

Access Modifier Descriptions
private มองเห็นได้เฉพาะที่อยู่ใน Unit เดียวกันกับ Object นี้เท่านั้น
public มองเห็นได้จากทุกที่ที่มีการ uses Unit นี้
ไม่ระบุ หมายถึง Public

Field Parameters

คือ ส่วนที่ถูกประกาศเป็นตัวแปรคล้ายกับการประกาศ var จากตัวอย่างข้างบน คือ FName และ FValue ตัวแปรเหล่านี้มักถูกประกาศเพื่อใช้เก็บค่าสำหรับ Property
จากตัวอย่างข้างบน จะเห็นว่า Field ถูกประกาศภายใต้คำว่า Private เพราะเราใช้ Field เหล่านี้ไว้เก็บค่า Property ที่ชื่อว่า Name และ Value จึงไม่ต้องการให้ Field เหล่านี้ถูกแก้ใขได้จากภายนอก

Properties

คือ คุณสมบัติของ Object ประกอบไปด้วย 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;
tutorial/record.1547179932.txt.gz · Last modified: 2019/01/11 11:12 by admin