跳到內容

Clipper 教程:開源 Clipper(s)/面向物件程式設計指南

來自華夏公益教科書

面向物件程式設計

[編輯 | 編輯原始碼]

Clipper 對 OOP(面向物件程式設計,從現在開始我們稱之為它的暱稱)的支援非常有限。它的繼任者 CA-Visual Objects 在這方面要先進得多。然而,Visual Objects 從未取得過巨大成功,第三方生產商為 Clipper 提供了 OOP 庫,其中最著名的是 Class(y)、TopClass、Fivewin 和 Clip4Win。

從安全距離看面向物件程式設計

[編輯 | 編輯原始碼]

假設我們正在處理給定點的笛卡爾座標的距離函式 (http://mathinsight.org/cartesian_coordinates)。我們將應用的公式是

分別用於實數線、歐幾里得平面和歐幾里得空間上的(歐幾里得)距離。

在程序式程式設計中,我們的函式看起來像這樣

? distance1d(4,-3)
? distance2d(2,-3,-1,-2)
? distance3d(1,1,1,4,4,4)

        FUNCTION distance1d( x1, x2 )
           RETURN sqrt((x2-x1)^2)

        FUNCTION distance2d( x1,y1,x2,y2 )
           RETURN sqrt((x2-x1)^2+(y2-y1)^2)

        FUNCTION distance3d( x1,y1,z1,x2,y2,z2 )
           RETURN sqrt((x1-x2)^2+(y1-y2)^2+(z1-z2)^2)

我們定義了三個函式,具有不同的名稱,它們以座標作為引數。但這樣做,我們需要為三維空間中的距離傳遞六個引數。

如果我們使用面向物件程式設計來做,我們可能會得到這樣的東西

#include "hbclass.ch"

   CREATE CLASS Point1D

   VAR Abscissa    // the abscissa of our point

METHOD New( Abscissa )    // Constructor

METHOD Distance( Point )

   ENDCLASS

   CREATE CLASS Point2D INHERIT Point1D

   VAR Ordinate    // the ordinate of our point

METHOD New( Abscissa, Ordinate )    // Constructor

METHOD Distance( Point )

   ENDCLASS

   CREATE CLASS Point3D INHERIT Point2D

   VAR Zcoord    // the Z-coordinate of our point

METHOD New( Zcoord )    // Constructor

METHOD Distance( Point )

   ENDCLASS

&& Constructors Zone
METHOD New( Abscissa ) CLASS Point1D

   ::Abscissa := Abscissa

   RETURN Self

METHOD New( Abscissa, Ordinate ) CLASS Point2D

   ::Abscissa := Abscissa
   ::Ordinate := Ordinate

   RETURN Self

METHOD New( Abscissa, Ordinate, Zcoord ) CLASS Point3D

   ::Abscissa := Abscissa
   ::Ordinate := Ordinate
   ::Zcoord := Zcoord

   RETURN Self

&&Distances Methods

METHOD Distance( Point ) CLASS Point1D

   RETURN Sqrt( ( Self:Abscissa - Point:Abscissa ) ^ 2 )

METHOD Distance( Point ) CLASS Point2D

   RETURN Sqrt( ( Self:Abscissa - Point:Abscissa ) ^ 2 + ( Self:Ordinate - Point:Ordinate ) ^ 2 )

METHOD Distance( Point ) CLASS Point3D

   RETURN Sqrt( ( Self:Abscissa - Point:Abscissa ) ^ 2 + ( Self:Ordinate - Point:Ordinate ) ^ 2 + ( Self:Zcoord - Point:Zcoord ) ^ 2 )

PROCEDURE Main()

   FirstPoint := Point1D():New( 3 )
   SecondPoint := Point1D():New( - 3 )
   ? FirstPoint:Abscissa
   ? FirstPoint:Distance( SecondPoint )
   ThirdPoint := Point2D():New( 2, - 3 )
   FourthPoint := Point2D():New( - 1, - 2 )
   ? ThirdPoint:Distance( FourthPoint )
   FifthPoint := Point3D():New( 1, 1, 1 )
   SixthPoint := Point3D():New( 4, 4, 4 )
   ? FifthPoint:Distance( SixthPoint )

   RETURN

在這裡,我們定義了三個,它們的建構函式,以及每個類的distance方法,並展示瞭如何使用它們。這也是繼承如何工作的簡單示例。其他概念是封裝資訊隱藏資料隱藏)、抽象多型性過載覆蓋方法。繼承在關鍵概念:重用中起著核心作用。如果一個類恰好是所需的,那麼它可以在軟體專案中重用;或者,如果它不是完全需要的,可以透過定義一個子類來擴充套件它。就像資料庫的設計一樣,面向物件類的設計也是一門藝術,有其原則,例如參見http://www.oodesign.com/http://www.codeproject.com/articles/567768/object-oriented-design-principles以及有關 UML 的頁面,如http://www.uml-diagrams.org/uml-object-oriented-concepts.html

首先要注意的是,我們從包含clipper 頭檔案hbclass.ch開始,這是 Class 命令的標頭檔案。

對物件變數和方法的訪問是透過冒號運算子完成的。字首雙冒號指的是具有更大範圍的變數(例如傳遞給方法的變數)。

在上面的程式碼中,我們定義了三個類,每個類都實現了一個 Point。例如,Point2D 被定義為一個擴充套件 Point1D 的類,即概念的泛化。為每個類提供了一個 Distance 方法。

像這樣的行

  ? FifthPoint:Distance( SixthPoint )

包含輸出命令?,對一個物件的引用(在本例中為FifthPoint),對 Distance 方法:Distance的呼叫,並將另一個點傳遞給它( SixthPoint )

也可以編寫一個接受兩個 Point 類引數的 Distance 函式,看起來像這樣

FUNCTION Distance ( Point1, Point2 )
   RETURN Sqrt( ( Point1:Abscissa - Point2:Abscissa ) ^ 2 + ( Point1:Ordinate - Point2:Ordinate ) ^ 2 + ( Point1:Zcoord - Point2:Zcoord ) ^ 2 )

   ? Distance( FifthPoint, SixthPoint )

然而,這不是面向物件程式設計,因為我們可以在非面嚮物件語言(如 Pascal 或 C)中使用相同的函式,並傳遞給它兩個名為 Point1 和 Point2 的structrecord(Pascal 稱之為)。

重要的是,物件內部的一些資料(由該物件的實際程式設計師設定)不能被物件使用者更改。舉一個現實生活中的例子,我們可以考慮汽車發動機。物件的提供者設定了氣缸的數量,我們沒有太多機會改變:我們必須把它視為一個常數。自然地,關於發動機有很多有趣的公式供工程師使用(一些可以在http://www.thecartech.com/subjects/engine/engine_formulas.htm上看到)。例如,計算發動機容積效率的公式,給定進入氣缸的空氣量和氣缸掃過的體積。這就是資料隱藏的重要性:沒有人需要知道這些資訊才能讓他的汽車行駛。此外,當有人設計發動機時,他們可能不希望使用者透過操作發動機來更改容積效率。在面向物件程式設計中,使用可見性修飾符訪問修飾符可以獲得相同的效果。

   [CREATE] CLASS <cClassName> [ FROM | INHERIT <cSuperClass1> [, ... ,<cSuperClassN>] ]
             [ MODULE FRIENDLY ] [ STATIC ] [ FUNCTION <cFuncName> ]

   [HIDDEN:]
      [ CLASSDATA | CLASSVAR  | CLASS VAR <DataName1>]
      [ DATA | VAR  <DataName1> [,<DataNameN>] [ AS <type> ] [ INIT <uValue> ]
             [[EXPORTED | VISIBLE] | [PROTECTED] | [HIDDEN]] [READONLY | RO] ]
      ...
      [ METHOD <MethodName>( [<params,...>] ) [CONSTRUCTOR] ]
      [ METHOD <MethodName>( [<params,...>] ) INLINE <Code,...> ]
      [ METHOD <MethodName>( [<params,...>] ) BLOCK  <CodeBlock> ]
      [ METHOD <MethodName>( [<params,...>] ) EXTERN <funcName>([<args,...>]) ]
      [ METHOD <MethodName>( [<params,...>] ) SETGET ]
      [ METHOD <MethodName>( [<params,...>] ) VIRTUAL ]
      [ METHOD <MethodName>( [<params,...>] ) OPERATOR <op> ]
      [ ERROR HANDLER <MethodName>( [<params,...>] ) ]
      [ ON ERROR <MethodName>( [<params,...>] ) ]
      ...
   [PROTECTED:]
      ...
   [VISIBLE:]
   [EXPORTED:]
      ...

   [FRIEND CLASS <ClassName,...>]
   [FRIEND FUNCTION <FuncName,...>]

   [SYNC METHOD <cSyncMethod>]

   ENDCLASS [ LOCK | LOCKED ]

另一個例子

[編輯 | 編輯原始碼]

w:Harbour (軟體) 中逐字複製

 #include "hbclass.ch"

 PROCEDURE Main()

    LOCAL oPerson

    CLS

    oPerson := Person():New( "Dave" )

    oPerson:Eyes := "Invalid"

    oPerson:Eyes := "Blue"

    Alert( oPerson:Describe() )

    RETURN

 CREATE CLASS Person

    VAR Name INIT ""

    METHOD New( cName )
    METHOD Describe()

    ACCESS Eyes INLINE ::pvtEyes
    ASSIGN Eyes( x ) INLINE iif( HB_ISSTRING( x ) .AND. x $ "Blue,Brown,Green", ::pvtEyes := x, Alert( "Invalid value" ) )

    PROTECTED:

    VAR pvtEyes

 ENDCLASS

 // Sample of normal Method definition
 METHOD New( cName ) CLASS Person

    ::Name := cName

    RETURN Self

 METHOD Describe() CLASS Person

    LOCAL cDescription

    IF Empty( ::Name )
       cDescription := "I have no name yet."
    ELSE
       cDescription := "My name is: " + ::Name + ";"
    ENDIF

    IF ! Empty( ::Eyes )
       cDescription += "my eyes' color is: " + ::Eyes
    ENDIF

    RETURN cDescription
華夏公益教科書