2016-2022 All Rights Reserved.平安財(cái)經(jīng)網(wǎng).復(fù)制必究 聯(lián)系QQ280 715 8082 備案號(hào):閩ICP備19027007號(hào)-6
本站除標(biāo)明“本站原創(chuàng)”外所有信息均轉(zhuǎn)載自互聯(lián)網(wǎng) 版權(quán)歸原作者所有。
大家好,小科來(lái)為大家解答以上問題。為什么要用C語(yǔ)言實(shí)現(xiàn)面向?qū)ο筮@個(gè)很多人還不知道,現(xiàn)在讓我們一起來(lái)看看吧!
1、不知道有多少人知道語(yǔ)言發(fā)展的歷史。早期C語(yǔ)言的語(yǔ)法功能其實(shí)比較簡(jiǎn)單。隨著應(yīng)用需求和場(chǎng)景的變化,C語(yǔ)言的語(yǔ)法功能也在不斷升級(jí)和變化。
2、雖然我們的教材有這樣一個(gè)結(jié)論:C語(yǔ)言是面向過(guò)程的語(yǔ)言,C語(yǔ)言是面向?qū)ο蟮木幊陶Z(yǔ)言,但是面向?qū)ο蟮母拍钤贑語(yǔ)言階段就已經(jīng)存在,并且已經(jīng)應(yīng)用到很多地方,比如一些操作系統(tǒng)內(nèi)核,通信協(xié)議。
3、面向?qū)ο缶幊?,即OOP(Object Oriented Programming)不是特定的語(yǔ)言或工具,它只是一種設(shè)計(jì)方法和設(shè)計(jì)思想,其最基本的三個(gè)特征是封裝、繼承和多態(tài)。
4、為什么要用C語(yǔ)言實(shí)現(xiàn)面向?qū)ο?/p>
5、在閱讀正文之前,一定會(huì)有讀者提出這樣的問題:我們有C面向?qū)ο笳Z(yǔ)言,為什么還要用C語(yǔ)言來(lái)實(shí)現(xiàn)面向?qū)ο竽兀?/p>
6、c,非面向?qū)ο笳Z(yǔ)言,也可以用面向?qū)ο蟮乃枷雽懗绦?。用面向?qū)ο蟮腃語(yǔ)言更容易實(shí)現(xiàn)面向?qū)ο缶幊?,但C語(yǔ)言的效率是其他面向?qū)ο缶幊陶Z(yǔ)言無(wú)法比擬的。
7、當(dāng)然,用C語(yǔ)言實(shí)現(xiàn)面向?qū)ο箝_發(fā)相對(duì)來(lái)說(shuō)比較難理解,這也是為什么大多數(shù)人學(xué)過(guò)C語(yǔ)言卻看不懂Linux內(nèi)核源代碼的原因。
8、所以這個(gè)問題其實(shí)很好理解。對(duì)C編程有一定經(jīng)驗(yàn)的讀者應(yīng)該能理解:與面向?qū)ο蟮腃語(yǔ)言相比,面向過(guò)程的C語(yǔ)言在代碼運(yùn)行效率和代碼數(shù)量上有很大的差異。在性能差、資源少的單片機(jī)中使用C語(yǔ)言面向?qū)ο缶幊田@得尤為重要。
9、有資格的
10、如果想用C語(yǔ)言實(shí)現(xiàn)面向?qū)ο?,首先需要具備一些基礎(chǔ)知識(shí)。比如:結(jié)構(gòu)、函數(shù)、指針、函數(shù)指針等。在C語(yǔ)言中,基類、派生、多態(tài)、繼承等。在C語(yǔ)言中。
11、首先,不僅僅是了解這些基礎(chǔ)知識(shí),還要有一定的編程經(jīng)驗(yàn),因?yàn)樯厦嬲f(shuō)“面向?qū)ο笫且环N設(shè)計(jì)方法和設(shè)計(jì)思想”,如果只是停留在字面上的理解,沒有這種設(shè)計(jì)思想是不行的。
12、所以不建議初學(xué)者使用C語(yǔ)言實(shí)現(xiàn)面向?qū)ο?,尤其是在真?shí)項(xiàng)目中。建議先練好基本功再用。
13、用C語(yǔ)言實(shí)現(xiàn)面向?qū)ο笥泻芏喾N方法。下面描述了最基本的封裝、繼承和多態(tài)。
14、密封和包裝
15、封裝是將數(shù)據(jù)和函數(shù)封裝到一個(gè)類中。其實(shí)大部分C語(yǔ)言程序員都近距離接觸過(guò)。
16、C標(biāo)準(zhǔn)庫(kù)中fopen()、fclose()、fread()、fwrite()等函數(shù)的操作對(duì)象都是FILE。數(shù)據(jù)的內(nèi)容是文件,數(shù)據(jù)的讀寫操作是fread()和fwrite(),fopen()類似于構(gòu)造函數(shù),fclose()是析構(gòu)函數(shù)。
17、這似乎很容易理解,所以讓我們實(shí)現(xiàn)基本的打包功能。
18、# ifndef SHAPE_H #定義SHAPE _ H
19、#包括
20、//形狀的屬性
21、這是 Shape 類的聲明,非常簡(jiǎn)單,很好理解。一般會(huì)把聲明放到頭文件里面 “Shape.h”。來(lái)看下 Shape 類相關(guān)的定義,當(dāng)然是在 “Shape.c” 里面。
再看下 main.c#include "shape.h"
// 構(gòu)造函數(shù)
void Shape_ctor(Shape * const me, int16_t x, int16_t y)
{
me->x = x;
me->y = y;
}
void Shape_moveBy(Shape * const me, int16_t dx, int16_t dy)
{
me->x += dx;
me->y += dy;
}
// 獲取屬性值函數(shù)
int16_t Shape_getX(Shape const * const me)
{
return me->x;
}
int16_t Shape_getY(Shape const * const me)
{
return me->y;
}
編譯之后,看看執(zhí)行結(jié)果:#include "shape.h" /* Shape class interface */
#include
/* for printf() */ int main()
{
Shape s1, s2; /* multiple instances of Shape */
Shape_ctor(&s1, 0, 1);
Shape_ctor(&s2, -1, 2);
printf("Shape s1(x=%d,y=%d)", Shape_getX(&s1), Shape_getY(&s1));
printf("Shape s2(x=%d,y=%d)", Shape_getX(&s2), Shape_getY(&s2));
Shape_moveBy(&s1, 2, -4);
Shape_moveBy(&s2, 1, -2);
printf("Shape s1(x=%d,y=%d)", Shape_getX(&s1), Shape_getY(&s1));
printf("Shape s2(x=%d,y=%d)", Shape_getX(&s2), Shape_getY(&s2));
return 0;
}
Shape s1(x=0,y=1)
Shape s2(x=-1,y=2)
Shape s1(x=2,y=-3)
Shape s2(x=0,y=0)
22、整個(gè)例子,非常簡(jiǎn)單,非常好理解。以后寫代碼時(shí)候,要多去想想標(biāo)準(zhǔn)庫(kù)的文件IO操作,這樣也有意識(shí)的去培養(yǎng)面向?qū)ο缶幊痰乃季S。
23、繼承
24、繼承就是基于現(xiàn)有的一個(gè)類去定義一個(gè)新類,這樣有助于重用代碼,更好的組織代碼。在 C 語(yǔ)言里面,去實(shí)現(xiàn)單繼承也非常簡(jiǎn)單,只要把基類放到繼承類的第一個(gè)數(shù)據(jù)成員的位置就行了。
25、例如,我們現(xiàn)在要?jiǎng)?chuàng)建一個(gè) Rectangle 類,我們只要繼承 Shape 類已經(jīng)存在的屬性和操作,再添加不同于 Shape 的屬性和操作到 Rectangle 中。
26、下面是 Rectangle 的聲明與定義:
#ifndef RECT_H
#define RECT_H
#include "shape.h" // 基類接口
// 矩形的屬性
typedef struct {
Shape super; // 繼承 Shape
// 自己的屬性
uint16_t width;
uint16_t height;
} Rectangle;
// 構(gòu)造函數(shù)
void Rectangle_ctor(Rectangle * const me, int16_t x, int16_t y,
uint16_t width, uint16_t height);
#endif /* RECT_H */
#include "rect.h"
// 構(gòu)造函數(shù)
void Rectangle_ctor(Rectangle * const me, int16_t x, int16_t y,
uint16_t width, uint16_t height)
{
/* first call superclass’ ctor */
Shape_ctor(&me->super, x, y);
/* next, you initialize the attributes added by this subclass... */
me->width = width;
me->height = height;
}
28、我們來(lái)看一下 Rectangle 的繼承關(guān)系和內(nèi)存布局:
29、因?yàn)橛羞@樣的內(nèi)存布局,所以你可以很安全的傳一個(gè)指向 Rectangle 對(duì)象的指針到一個(gè)期望傳入 Shape 對(duì)象的指針的函數(shù)中,就是一個(gè)函數(shù)的參數(shù)是 “Shape *”,你可以傳入 “Rectangle *”,并且這是非常安全的。這樣的話,基類的所有屬性和方法都可以被繼承類繼承!
#include "rect.h"
#include
int main()
{
Rectangle r1, r2;
// 實(shí)例化對(duì)象
Rectangle_ctor(&r1, 0, 2, 10, 15);
Rectangle_ctor(&r2, -1, 3, 5, 8);
printf("Rect r1(x=%d,y=%d,width=%d,height=%d)",
Shape_getX(&r1.super), Shape_getY(&r1.super),
r1.width, r1.height);
printf("Rect r2(x=%d,y=%d,width=%d,height=%d)",
Shape_getX(&r2.super), Shape_getY(&r2.super),
r2.width, r2.height);
// 注意,這里有兩種方式,一是強(qiáng)轉(zhuǎn)類型,二是直接使用成員地址
Shape_moveBy((Shape *)&r1, -2, 3);
Shape_moveBy(&r2.super, 2, -1);
printf("Rect r1(x=%d,y=%d,width=%d,height=%d)",
Shape_getX(&r1.super), Shape_getY(&r1.super),
r1.width, r1.height);
printf("Rect r2(x=%d,y=%d,width=%d,height=%d)",
Shape_getX(&r2.super), Shape_getY(&r2.super),
r2.width, r2.height);
return 0;
}
輸出結(jié)果:
本文到此結(jié)束,希望對(duì)大家有所幫助。
2016-2022 All Rights Reserved.平安財(cái)經(jīng)網(wǎng).復(fù)制必究 聯(lián)系QQ280 715 8082 備案號(hào):閩ICP備19027007號(hào)-6
本站除標(biāo)明“本站原創(chuàng)”外所有信息均轉(zhuǎn)載自互聯(lián)網(wǎng) 版權(quán)歸原作者所有。