Delphi × Object Pascal × 繁體中文完整教學

Delphi 編程語言詳細教學網站

這是一個以單頁式 HTML 製作的 Delphi 教學網站,內容包含語法基礎、程式流程控制、 程序與函式、物件導向、例外處理、基礎範例、進階範例,以及可立即作答的小測驗。 適合初學者快速建立 Delphi 與 Object Pascal 的整體觀念。

課程總覽

Delphi 是一種高階、強型別、編譯式語言,建立於 Object Pascal 之上, 同時支援結構化程式設計與物件導向設計。初學 Delphi 時,建議先掌握程式結構、 資料型別、流程控制,再進入函式、類別與例外處理。這樣閱讀現成程式或進一步學習 VCL / FMX 時會更順利。

你將學到什麼?

  • Delphi 程式的基本骨架與單元概念
  • 變數、常數、常見資料型別
  • ifcaseforwhile 等控制流程
  • 程序(procedure)與函式(function)的差異
  • class、field、method、property、constructor、destructor
  • try...excepttry...finally 的用途
  • 陣列、Record、泛型、檔案讀寫與 Unit 模組拆分
適合初學者 含完整範例 含互動小測驗

Delphi 語法教學

以下內容以初學者角度整理,並搭配簡短說明與可直接閱讀的 Delphi 程式片段。 若你已學過 Pascal,會發現 Delphi 在語法上延續了 Pascal 的清楚結構, 並加入更完整的物件導向能力。

1. 程式結構:認識 Delphi 程式骨架

核心觀念:program、uses、宣告區、begin...end.

Delphi 專案通常會有一個主程式檔(例如 .dpr)與多個單元檔 (.pas)。對初學者來說,可以先把它理解成: 程式名稱、使用哪些模組、先宣告要用的東西,最後再把執行的程式碼放進 begin ... end. 之中。

program HelloDelphi;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

begin
  Writeln('Hello, Delphi!');
  Readln;
end.
重點整理:
  • program HelloDelphi;:定義程式名稱。
  • uses:引入需要的單元,例如 System.SysUtils
  • begin ... end.:主程式的執行區塊,最後的 end. 有句點。

2. 變數、常數與常見資料型別

核心觀念:var、const、Integer、Double、Boolean、String

Delphi 是強型別語言,因此變數在使用前通常必須先宣告型別。 常見型別包括整數、浮點數、布林值與字串。你也可以使用 const 宣告固定不變的常數。

program VariablesDemo;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

const
  SiteName = 'Delphi 學習站';

var
  Age: Integer;
  Price: Double;
  IsPassed: Boolean;
  UserName: string;

begin
  Age := 20;
  Price := 199.5;
  IsPassed := True;
  UserName := '小明';

  Writeln('網站名稱:', SiteName);
  Writeln('姓名:', UserName);
  Writeln('年齡:', Age);
  Writeln('價格:', Price:0:2);
  Writeln('是否通過:', IsPassed);
  Readln;
end.
型別 用途 範例
Integer 整數 Score: Integer;
Double 浮點數、帶小數 Price: Double;
Boolean 真假值 IsOpen: Boolean;
string 文字內容 Name: string;
Char 單一字元 Grade: Char;

3. 流程控制:if、case、for、while、repeat

核心觀念:條件判斷、分支、迴圈

撰寫程式時,常常需要根據條件做不同處理,或重複執行某些步驟。 Delphi 提供多種清楚的流程控制語法。

if...then...else

if Score >= 60 then
  Writeln('及格')
else
  Writeln('不及格');

case

case Grade of
  'A': Writeln('優秀');
  'B': Writeln('良好');
  'C': Writeln('普通');
else
  Writeln('請再努力');
end;

for 迴圈

for I := 1 to 5 do
  Writeln('第 ', I, ' 次');

while / repeat

while Count < 3 do
begin
  Inc(Count);
  Writeln(Count);
end;

repeat
  Dec(Count);
until Count = 0;
記憶技巧:
  • if:只有少數條件分支時最好用。
  • case:固定選項很多時更清楚。
  • for:知道次數時用。
  • while:先判斷條件,再決定要不要進入。
  • repeat:至少執行一次,再檢查條件。

4. 程序與函式:procedure 與 function 的差異

核心觀念:回傳值、參數模式、Result

在 Delphi 中,程序(procedure)不回傳值,函式(function)會回傳值。 兩者都能接收參數。常見參數模式包含一般值參數、varconstout

program FunctionDemo;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

procedure SayHello(const AName: string);
begin
  Writeln('你好,', AName);
end;

function AddNumbers(A, B: Integer): Integer;
begin
  Result := A + B;
end;

procedure Increase(var Value: Integer);
begin
  Inc(Value);
end;

var
  Total: Integer;
begin
  SayHello('Delphi 學習者');

  Total := AddNumbers(10, 20);
  Writeln('總和:', Total);

  Increase(Total);
  Writeln('加一後:', Total);

  Readln;
end.
語法 用途 說明
procedure 執行動作 不回傳值,適合顯示、寫檔、更新資料
function 計算結果 有回傳值,常透過 Result := ... 指定
const 唯讀參數 避免被函式內部改動
var 可修改參數 呼叫後原變數可能被改變
out 輸出參數 多用於由程序產生結果給外部

5. 類別與物件:Object Pascal 的 OOP 核心

核心觀念:class、field、method、property、constructor、destructor

Delphi 的物件導向設計以類別(class)為基礎。類別可以包含欄位(field)、 方法(method)與屬性(property)。建立物件時通常呼叫建構子 Create,使用完畢後釋放資源。

program ClassDemo;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

type
  TStudent = class
  private
    FName: string;
    FAge: Integer;
  public
    constructor Create(const AName: string; AAge: Integer);
    procedure Introduce;
    property Name: string read FName write FName;
    property Age: Integer read FAge write FAge;
  end;

constructor TStudent.Create(const AName: string; AAge: Integer);
begin
  FName := AName;
  FAge := AAge;
end;

procedure TStudent.Introduce;
begin
  Writeln('我是 ', FName, ',今年 ', FAge, ' 歲。');
end;

var
  Student: TStudent;
begin
  Student := TStudent.Create('小華', 18);
  try
    Student.Introduce;
  finally
    Student.Free;
  end;

  Readln;
end.

Field

儲存物件內部資料,例如 FNameFAge

Method

物件能做的事,例如 Introduce

Property

對外提供較安全的資料存取介面,例如 NameAge

常見可見性:
  • private:類別內部使用。
  • protected:本類別與子類別可用。
  • public:外部可使用。
  • published:常見於元件屬性與 RTTI。

6. 例外處理:讓程式更穩定

核心觀念:try...except、try...finally、raise

例外(Exception)是在執行過程中發生錯誤或特殊事件時的處理機制。 Delphi 常用兩種寫法:一種是捕捉錯誤並處理,另一種是確保資源一定會被釋放。

try...except

try
  Value := StrToInt('abc');
except
  on E: EConvertError do
    Writeln('轉換失敗:', E.Message);
end;

try...finally

Obj := TStudent.Create('小美', 19);
try
  Obj.Introduce;
finally
  Obj.Free;
end;

若你想主動拋出錯誤,也可以使用 raise

if Age < 0 then
  raise Exception.Create('年齡不可為負數');

7. 初學 Delphi 的建議學習順序

核心觀念:先語法,再模組,再 GUI 框架

  1. 先熟悉主控台輸出與變數宣告,理解 WritelnReadln
  2. 練習條件判斷與迴圈,建立演算法感。
  3. 把重複邏輯整理成 procedure / function。
  4. 開始寫 class,理解建構子、方法與 property。
  5. 最後再進入 VCL 或 FireMonkey 做視窗程式與 GUI 應用。
學習策略: 若你曾學過 C、Java 或 C#,可以把 Delphi 想成語法更清楚、結構更穩定的 Object Pascal。 若完全沒學過程式,建議先多寫小型主控台題目,例如加總、成績判斷、資料輸入與格式化輸出。

基本範例應用

以下提供幾個從基礎到進階的 Delphi 小範例。這些例子不只幫助你閱讀語法, 也能讓你理解實際應用時該如何切分程式。

範例 1

成績判斷系統

輸入分數後,自動判斷等第與是否及格,練習 ifcase

if Score >= 90 then
  Grade := 'A'
else if Score >= 80 then
  Grade := 'B'
else if Score >= 70 then
  Grade := 'C'
else if Score >= 60 then
  Grade := 'D'
else
  Grade := 'E';
範例 2

簡易加總計算器

利用函式回傳結果,建立可重複使用的計算邏輯。

function Sum(A, B: Integer): Integer;
begin
  Result := A + B;
end;
範例 3

學生資料物件

透過 class 封裝姓名與年齡,示範 OOP 的基本寫法。

type
  TStudent = class
  private
    FName: string;
  public
    procedure SetName(const AName: string);
  end;
範例 4

安全轉換字串為整數

利用例外處理避免使用者輸入錯誤導致程式中止。

try
  N := StrToInt(InputText);
except
  on E: EConvertError do
    Writeln('請輸入有效整數');
end;

更完整的 Delphi 範例實作

下面這一區加入了更貼近實際開發的 Delphi 範例,包括動態陣列、Record、檔案讀寫、 類別繼承、多型、泛型容器與 Unit 拆分。這些主題能幫助你從「看懂語法」 進一步走到「能自己拆模組與寫小型應用」。

範例 5:動態陣列與平均成績計算

重點:dynamic array、for 迴圈、函式回傳值

這個範例示範如何使用動態陣列儲存多筆成績,並用函式計算平均值。

program ArrayAverageDemo;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

function Average(const Scores: array of Integer): Double;
var
  I, Sum: Integer;
begin
  Sum := 0;
  for I := Low(Scores) to High(Scores) do
    Sum := Sum + Scores[I];

  if Length(Scores) = 0 then
    Result := 0
  else
    Result := Sum / Length(Scores);
end;

var
  Scores: array of Integer;
  I: Integer;
begin
  SetLength(Scores, 5);
  Scores[0] := 85;
  Scores[1] := 92;
  Scores[2] := 76;
  Scores[3] := 88;
  Scores[4] := 95;

  Writeln('所有成績:');
  for I := Low(Scores) to High(Scores) do
    Writeln('第 ', I + 1, ' 筆:', Scores[I]);

  Writeln('平均成績:', FormatFloat('0.00', Average(Scores)));
  Readln;
end.

範例 6:Record 記錄型別管理商品資料

重點:record、自訂資料結構、格式化輸出

如果資料結構不需要完整的 class 行為,只是想把多個欄位整理在一起, 可以先用 Record。這很適合拿來管理商品、座標、學生資料等。

program RecordProductDemo;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

type
  TProduct = record
    ID: Integer;
    Name: string;
    Price: Double;
    InStock: Boolean;
  end;

procedure PrintProduct(const AProduct: TProduct);
begin
  Writeln('商品編號:', AProduct.ID);
  Writeln('商品名稱:', AProduct.Name);
  Writeln('商品價格:', FormatFloat('0.00', AProduct.Price));
  Writeln('是否有庫存:', BoolToStr(AProduct.InStock, True));
end;

var
  Product: TProduct;
begin
  Product.ID := 1001;
  Product.Name := 'Delphi 教學書';
  Product.Price := 580;
  Product.InStock := True;

  PrintProduct(Product);
  Readln;
end.

範例 7:字串處理與輸入驗證

重點:Trim、UpperCase、Length、條件判斷

實際寫程式時,使用者輸入常常有多餘空白、大小寫不一致等問題。 這個範例示範基本的字串清理與驗證。

program StringValidationDemo;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

var
  UserInput, CleanText: string;
begin
  Write('請輸入你的代號:');
  Readln(UserInput);

  CleanText := Trim(UserInput);
  CleanText := UpperCase(CleanText);

  if Length(CleanText) = 0 then
    Writeln('錯誤:不可輸入空白內容')
  else
  begin
    Writeln('整理後的內容:', CleanText);
    Writeln('字元長度:', Length(CleanText));
  end;

  Readln;
end.

範例 8:檔案寫入與讀取

重點:TStringList、SaveToFile、LoadFromFile、try...finally

這是一個非常實用的入門範例:先把幾行資料寫入文字檔,再從檔案讀回來顯示。 同時也練習物件建立後要搭配 try...finally 釋放資源。這類資源管理方式 也符合 Delphi 例外處理與物件生命週期的核心做法。

program FileReadWriteDemo;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  System.Classes;

var
  Lines: TStringList;
  I: Integer;
begin
  Lines := TStringList.Create;
  try
    Lines.Add('Delphi');
    Lines.Add('Object Pascal');
    Lines.Add('File Demo');
    Lines.SaveToFile('demo.txt');

    Writeln('已寫入 demo.txt');
    Writeln('----------');

    Lines.Clear;
    Lines.LoadFromFile('demo.txt');

    Writeln('讀取檔案內容:');
    for I := 0 to Lines.Count - 1 do
      Writeln(Lines[I]);
  finally
    Lines.Free;
  end;

  Readln;
end.

範例 9:類別繼承與多型

重點:class inheritance、virtual、override

當多個類別有共同特徵時,可以先建立父類別,再讓子類別繼承並覆寫方法。 這是 Delphi 物件導向很重要的一步。

program InheritanceDemo;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

type
  TAnimal = class
  public
    procedure Speak; virtual;
  end;

  TDog = class(TAnimal)
  public
    procedure Speak; override;
  end;

  TCat = class(TAnimal)
  public
    procedure Speak; override;
  end;

procedure TAnimal.Speak;
begin
  Writeln('動物發出聲音');
end;

procedure TDog.Speak;
begin
  Writeln('狗:汪汪');
end;

procedure TCat.Speak;
begin
  Writeln('貓:喵喵');
end;

var
  Animal: TAnimal;
begin
  Animal := TDog.Create;
  try
    Animal.Speak;
  finally
    Animal.Free;
  end;

  Animal := TCat.Create;
  try
    Animal.Speak;
  finally
    Animal.Free;
  end;

  Readln;
end.

範例 10:例外處理與安全數字轉換

重點:StrToInt、try...except、EConvertError

這個範例很適合初學者,因為使用者輸入常常不可靠。 如果直接轉型失敗,程式可能中斷;加上例外處理後就能優雅地回應錯誤。

program SafeConvertDemo;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

var
  InputText: string;
  Number: Integer;
begin
  Write('請輸入整數:');
  Readln(InputText);

  try
    Number := StrToInt(InputText);
    Writeln('你輸入的整數是:', Number);
  except
    on E: EConvertError do
      Writeln('輸入格式錯誤,請輸入有效整數。');
  end;

  Readln;
end.

範例 11:使用泛型 TList<string> 管理資料

重點:Generics、TList、for..in

若你需要動態增加資料筆數,泛型容器會比固定大小陣列更方便。 這是現代 Delphi 寫法中很常見的資料管理方式。

program GenericListDemo;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  System.Generics.Collections;

var
  Names: TList<string>;
  NameItem: string;
begin
  Names := TList<string>.Create;
  try
    Names.Add('Alice');
    Names.Add('Bob');
    Names.Add('Cindy');

    Writeln('名單內容:');
    for NameItem in Names do
      Writeln(NameItem);
  finally
    Names.Free;
  end;

  Readln;
end.

範例 12:Unit 模組拆分

重點:unit、interface、implementation、uses

當程式逐漸變大時,就不應把所有函式都寫在同一個主程式裡。 Delphi 通常會把可重複使用的功能拆到 Unit。這也是 Delphi 程式結構中的核心概念之一。

檔案一:UMathHelper.pas

unit UMathHelper;

interface

function Max2(A, B: Integer): Integer;
function Min2(A, B: Integer): Integer;

implementation

function Max2(A, B: Integer): Integer;
begin
  if A > B then
    Result := A
  else
    Result := B;
end;

function Min2(A, B: Integer): Integer;
begin
  if A < B then
    Result := A
  else
    Result := B;
end;

end.

檔案二:UnitDemo.dpr

program UnitDemo;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  UMathHelper;

begin
  Writeln('較大值:', Max2(10, 25));
  Writeln('較小值:', Min2(10, 25));
  Readln;
end.

範例 13:簡易學生管理 class 陣列版

重點:class、dynamic array、procedure、資料走訪

這個範例把前面學過的 class、陣列與方法整合起來,算是一個比較完整的小型練習。

program StudentManagerDemo;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

type
  TStudent = class
  private
    FName: string;
    FScore: Integer;
  public
    constructor Create(const AName: string; AScore: Integer);
    procedure PrintInfo;
    property Name: string read FName;
    property Score: Integer read FScore;
  end;

constructor TStudent.Create(const AName: string; AScore: Integer);
begin
  FName := AName;
  FScore := AScore;
end;

procedure TStudent.PrintInfo;
begin
  Writeln('姓名:', FName, ',分數:', FScore);
end;

var
  Students: array of TStudent;
  I: Integer;
begin
  SetLength(Students, 3);
  Students[0] := TStudent.Create('小明', 88);
  Students[1] := TStudent.Create('小美', 92);
  Students[2] := TStudent.Create('小華', 75);

  try
    Writeln('學生清單:');
    for I := Low(Students) to High(Students) do
      Students[I].PrintInfo;
  finally
    for I := Low(Students) to High(Students) do
      Students[I].Free;
  end;

  Readln;
end.

常見問題

如果你剛接觸 Delphi,下面這些問題通常最容易遇到。

Delphi 建立在 Object Pascal 之上,語法與 Pascal 有很深的繼承關係, 但 Delphi 加入了更完整的物件導向、例外處理、類別、屬性、泛型與現代開發環境支援。

建議先學主控台。因為 GUI 會同時引入事件、元件與介面邏輯, 對新手來說容易分心。先掌握語法與資料結構,再做視窗應用會更穩。

如果你的程式只是「做一件事」而不需要回傳值,通常用 procedure; 如果你希望得到計算結果,例如總和、布林判斷、字串處理結果,就用 function。

field 是物件內部實際儲存資料的地方;property 則是對外存取資料的介面, 可以決定如何讀取與寫入,因此更符合封裝精神。

Delphi 小測驗

完成以下題目後按下「送出答案」,系統會立即計算分數並顯示建議。

作答進度:0 / 6

1. Delphi 主程式主體通常由哪個關鍵字開始?

2. 哪一種 Delphi 語法會回傳值?

3. 若要讓參數能在 procedure 內被修改並影響外部變數,常用哪個參數模式?

4. 下列哪個最適合描述 property?

5. 若要不論是否發生錯誤都釋放物件,最常用哪個結構?

6. 哪個迴圈保證至少執行一次?

你的分數:0 / 6