介簡:linux
Redy的開發語言是C,但在源碼中,有不少地方都使用到了面向對象編程的方法,例如:在基本數據類型這一個模塊,全部的數據類型都繼承robject;在抽象語法樹模塊,全部的節點都繼承astobjct。在linux內核中,也有不少是使用的面向對象方法,在虛擬文件系統,驅動模型中均可以看到。c語言是一種結構化編程語言,以模塊工能和處理過程設計爲主,實現數據與代碼分隔化。面向對象方法論中,核心是類,類是用於創造對象的模板,其三要素爲:封裝,繼承,多態。C語言自己對面向對象的支持很弱,但能夠經過一些技巧來實現。下面經過一個具體的實例來講明實現這此技巧。編程
實例介簡:編程語言
在幾何中,全部的幾何類型都繼承父類「形狀(shape)」,父類「形狀」有兩處屬性s_type和s_name。其中s_type用於表示該形狀所屬的類型,s_name用於表於該形狀態的名稱。並且父類shape還有兩個虛接口,一個爲shape_area用於返回該形狀的面積,一個爲shape_perimeter用於返回該形狀的周長。所子繼承「形狀」的子類都必須實現這兩個接口。ide
struct shape;測試
struct shape_ops設計
{對象
/*返回幾何體的面積*/繼承
float (*so_area)(struct shape*); 接口
/*返回幾何體的周長*/開發
int (*so_perimeter)(struct shape*);
};
struct shape
{
int* s_type;
char* s_name;
struct shape_ops* s_ops; /*虛接口,全部子類必須實現*/
};
float shape_area(struct shape* s) /*求形狀面積*/
{
return s->s_ops->so_area(s);
}
int shape_perimeter(struct shape* s) /*求周長*/
{
return s->s_ops->so_perimeter(s);
}
幾何體「三角形(triangle)」繼承父類「形狀」,而且實現了父類的兩個虛接口。「三角形」有三條邊,分別用t_side_a,t_side_b,t_side_c來表於三條邊的長度。
/*三角形*/
struct triangle
{
struct shape t_base;
int t_side_a;
int t_side_b;
int t_side_c;
};
float triangle_area(struct shape* s) /*三角形面積,用海倫公式*/
{
struct triangle* t=(struct triangle*)s;
int a=t->t_side_a;
int b=t->t_side_b;
int c=t->t_side_c;
float p=(a+b+c)/2;
return sqrt(p*(p-a)*(p-b)*(p-c));
}
int triangle_perimeter(struct shape* s) /*三角形周長*/
{
struct triangle* t=(struct triangle*)s;
int a=t->t_side_a;
int b=t->t_side_b;
int c=t->t_side_c;
return a+b+c;
}
struct shape_ops triangle_ops= /*對父類虛接口的實現*/
{
triangle_area,
triangle_perimeter,
};
struct triangle* triangle_create(int a,int b,int c) /*建立三角形*/
{
struct triangle* ret=(struct triangle*)malloc(sizeof (*ret));
ret->t_base.s_name="triangle";
ret->t_base.s_ops=&triangle_ops;
ret->t_side_a=a;
ret->t_side_b=b;
ret->t_side_c=c;
return ret;
}
幾何體「矩形(rectangle)」繼承父類「形狀」,一樣也實現的父類的兩個虛接口。有兩個屬性r_width和r_height,分別表示矩形的長和寬。
/*矩形*/
struct rectangle
{
struct shape r_base;
int r_width;
int r_height;
};
float rectangle_area(struct shape* s) /*矩形面積*/
{
struct rectangle* r=(struct rectangle*)s;
return r->r_width*r->r_height;
}
int rectangle_perimeter(struct shape* s)/*矩形周長*/
{
struct rectangle* r=(struct rectangle*)s;
return (r->r_width+r->r_height)*2;
}
struct shape_ops rectangle_ops= /*對父類虛接口的實現*/
{
rectangle_area,
rectangle_perimeter,
};
struct rectangle* rectangle_create(int width, int height) /*建立矩形*/
{
struct rectangle* ret=(struct rectangle*)malloc(sizeof(*ret));
ret->r_base.s_name="rectangle";
ret->r_base.s_ops=&rectangle_ops;
ret->r_height=height;
ret->r_width=width;
return ret;
}
測試代碼:
int main()
{
struct shape* s[4];
s[0]=triangle_create(5,5,4);
s[1]=triangle_create(3,4,5);
s[2]=rectangle_create(10,12);
s[3]=rectangle_create(5,8);
int i=0;
for(i=0;i<4;i++)
{
float area=shape_area(s[i]);
int perimeter=shape_perimeter(s[i]);
char* name=s[i]->s_name;
printf("name:%s ,area:%.2f ,perimeter:%d\n",name,area,perimeter);
}
return 0;
}
運行結果:
name:triangle ,area:9.17 ,perimeter:14
name:triangle ,area:6.00 ,perimeter:12
name:rectangle ,area:120.00 ,perimeter:44
name:rectangle ,area:40.00 ,perimeter:26