終於完成物件導向的設計,包括用於指導撰寫程式的「類別模型」和「動態模型」。
以物件導向的方式進行設計,只是進攻的前奏,撰寫程式才是最終的目標。
雖然物件導向的理論、方法、技巧經過多年的發展後,業界已經形成基本統一的認知,但並未出現一種統一的「物件導向程式語言」。
每種語言都會根據自己的需求、特徵,選擇支援或不支援物件導向,或者只支援部份物件導向的特性。
各種語言對物件導向支援的程度和方式,導致將其設計轉換為程式碼時,還需要做一次翻譯或轉換的過程。
因此,若想充分應用物件導向,除了掌握物件導向的概念、方法、技巧外,還得要精通程式語言與物件導向相關的特性。
本系列以 C/C++ 為主要程式語言,並詳細描述它們與物件導向相關的特性;在 GUI 的設計上,我們會採用 C# 及 Python 來說明。
這邊只是先擷取出 C++ 跟物件導向相關的資料,後續我們會再參考「API Design for C++」一書來了解更多的細節。
C++是第一個廣泛流行的物件導向程式語言,至今依然佔據程式語言榜單的前幾名。
儘管 C++ 促進了物件導向程式設計的發展,但它的複雜性也伴隨著較大的爭議;尤其是與物件導向相關的特性,光是各式各樣的術語,就能把剛入門的程式開發者搞得頭昏眼花。
尤其 C++ 相容於 C 語言的特性,導致在程式中,一不留神就會出現「物件導向」和「程序導向」風格混雜的情況。
正因為 C++ 這種特性,當採用 C++ 進行物件導向程式設計時,就需要花費更多的時間和精力,以便瞭解 C++ 物件導向的特型。
C++ 類別透過關鍵字 class 來標示。
類別的定義包含兩部分:類別標頭 (header, .h),由 class 和後面的類別名稱組成;類別實作(source, .cpp ),由一對大括弧包圍起來,裡面包含屬性和方法的宣告。
例如:
//NImage.h
#ifndef _NIMAGE_H
#define _NIMAGE_H
#include <windows.h>
#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)
class NImage
{
private:
HBITMAP hBitmap;
LPBYTE lpBits;
int nWidth;
int nHeight;
int nBitCount;
int nBytesPerLine;
int nBytesPerPixel;
int nNumColors;
int nSize;
HDC hMemDC;
public:
NImage();
~NImage();
public:
// Overrides
virtual BOOL BitBlt(HDC,int,int,int,int,int,int,DWORD);
virtual BOOL MaskBlt(HDC,int,int,HBITMAP,DWORD);
virtual HDC GetDC();
virtual void ReleaseDC();
void Create(int Width,int Height,int Bits,DWORD dwFlags=0);
BOOL IsNull();
void Destroy();
int GetWidth();
int GetHeight();
int GetBPP();
int GetPitch();
int GetMaxColorTableEntries();
BYTE* GetPixelAddress(int x,int y);
COLORREF GetPixel(int x,int y );
void GetColorTable(int m, int n, RGBQUAD* ColorTab);
void SetColorTable(int m, int n, RGBQUAD* ColorTab);
BOOL LoadBMP(char* filename);
BOOL SaveBMP(char* filename);
HBITMAP* GetBitmap();
};
#endif //!_NIMAGE_H
在 C++ 中,宣告和定義是分開的,上述程式碼只是 NImage 類別的宣告,其方法需要在定義檔(source, .cpp)實作。
例如:
//NImage.cpp
#include <stdio.h>
#include "NImage.h"
NImage::NImage()
{
hBitmap=NULL;
hMemDC=NULL;
}
NImage::~NImage()
{
Destroy();
}
BOOL NImage::IsNull()
{
if (hBitmap==NULL)
return(TRUE);
else
return(FALSE);
}
void NImage::Destroy()
{
if (hBitmap!=NULL)
{
DeleteObject(hBitmap);
hBitmap=NULL;
}
}
C++類別的屬性和方法,都可以指定三種存取控制方式:
C++ 是分段的存取控制方式,每段的開始透過存取限定詞加上一個冒號 ( : ),直到另一個分段開始時結束,或者到類別定義結束。
一個類別允許包含多個存取控制段;如果沒有指定存取限定詞,則預設為 private。