好了,現(xiàn)在我要給大家講講面向?qū)ο蟮囊恍┲R。上次說到了,面向?qū)ο笫且环N對現(xiàn)實世界理解和抽象的方法,是計算機編程技術(shù)發(fā)展到一定階段后的產(chǎn)物。一般地,面向?qū)ο缶哂欣^承性、封裝性、多態(tài)性三個特征。 舉個簡單的例子吧,現(xiàn)在我讓你去用計算器計算3*4的結(jié)果,你會這么做呢?仔細想想,流程應(yīng)該如下。 (1)買一個計算器; (2)輸入3*4; (3)按下=鍵,獲得結(jié)果。 這正好對應(yīng)這三行代碼: (1)Calculator c; (2)c.inputFormula(“3*4”); (3)c.getResult(); 所以說,面向?qū)ο笈c現(xiàn)實非常貼合,這就是面向?qū)ο笫軞g迎的原因之一。 有人又會疑惑了,我怎么知道計算器對象具有哪些函數(shù)呢,函數(shù)的參數(shù)掃是什么,返回值又是什么?有沒有一個標(biāo)準(zhǔn)或者是文檔呢? 很負責(zé)的告訴你,有的。計算器有說明書,面向?qū)ο缶陀蠥PI。API:application Programming Interface,應(yīng)用程序編程接口。 例如,這里的計算器類的API如下所示: 根據(jù)這個API,我們可以隨心所欲地使用計算器啦~ 然后有人又有疑惑了,你的API中為什么setFormula()函數(shù)要重載呢?為什么接收C++的字符串之外還要寫一個接收C風(fēng)格的字符串呢? 這其實就是面向?qū)ο蟮亩鄳B(tài)性。通俗一點說,就是多種選擇隨我選。一個面向?qū)ο蟮膬?yōu)質(zhì)代碼,往往就是盡可能多給與對方(使用者)更多的選擇。 此外我再通俗地說一下封裝性:即內(nèi)部存儲和實現(xiàn)不關(guān)我的事。例如在計算器類中,getResult()函數(shù)是如何工作的,這個或許是字符串解析吧,或許是利用棧結(jié)構(gòu),或許是遞歸……反正我是不知道,也沒有必要知道,我只要會用就行了。就好像我們買電視,沒有人說一定要知道電視的結(jié)構(gòu)、組成才能看電視吧。面向?qū)ο笠彩且粯拥脑怼? 最后則是面向?qū)ο蟮睦^承性。例如: (派生)人→學(xué)生→研究生 (繼承)研究生→學(xué)生→人 就是典型的一個繼承。 我們寫三個類(人、學(xué)生、研究生)的“戀愛”方法吧。
class Person
{int age;
void love(){cout<<
"fall in love at will" <<endl;}}
class Student:
public Person
{
int age;
void love(){
cout <<
"fall in love seriously" <<endl;}}
class Postgraduate:
public Student
{
int age;
void love(){
cout <<
"fall in love maturely" <<endl;}}
總而言之,這三類人是“隨心所欲的戀愛”,“認真的戀愛”,“成熟的戀愛”。如果這個時候定義一個研究生對象gth,調(diào)用“戀愛”方法后,輸出的肯定是“成熟的戀愛”。
Postgraduate gth;
gth.love();
這個就稱為方法(函數(shù))覆蓋(重寫)。當(dāng)然這里的覆蓋并不是指一定訪問不到了,只是使用起來好像是訪問不到了。如果想要完全覆蓋,需要使用虛函數(shù)。這里就不再贅述。 下面的概念很有趣。對于自然界很多物體(具體的或抽象的),一般都可以建立對象(實例化)。但是,對于一部分概念,其一般為一類統(tǒng)稱,一般不希望其實例化,例如水果、動物、蔬菜……例如,“xxx,給我拿一個水果來。”這句話其實就是有問題的。 但是,“水果”作為一個概念,的確擁有一些屬性(例如VC含量,重量)和方法(吃、存儲)等。所以我們希望定義一個類,其指定了一部分屬性和方法(方法空實現(xiàn)),該類不可實例化,只能通過繼承后再實例,達到自然界的高度仿真。 我們需要純虛函數(shù)來實現(xiàn)這個規(guī)律。 我們先寫水果類:
class Fruit
{
private :
double vcContent;
double weight;
public :
virtual void eat ()=
0 ;
virtual void store()=
0 ;
};
再寫蘋果類:
class Apple:
public Fruit
{
public :
void eat (){cout<<
"just eat it :)" <<endl;}
void store(){cout<<
"stored in shadow" <<endl;}
};
最后是main()函數(shù)
void main()
{
Apple apple;apple.eat();apple.store();
}
最后,我們來一個生動的實戰(zhàn)例子,來說明面向?qū)ο笫侨绾尉幊痰摹?/p>
NOJ實戰(zhàn) 1058 Tom和Jerry在10*10的方格中: …….. ……*… …….. ………. …*.C…. …..… …*…… ..M……* ….…. ..…… C=Tom(貓) M=Jerry(老鼠) *=障礙物 .=空地 他們各自每秒中走一格,如果在某一秒末他們在同一格中,我們稱他們“相遇”。注意,“對穿”是不算相遇的。 他們移動方式相同:平時沿直線走,下一步如果會走到障礙物上去或者出界,就用1秒的時間做一個右轉(zhuǎn)90度。一開始他們都面向北方。 編程計算多少秒以后他們相遇。 我們簡要的對這個現(xiàn)實世界的產(chǎn)物進行抽象和建模: 然后我們回想,為什么位置和方向都是向量呢?看下面一張圖就能明了。 接下來,我們就可以進行代碼的編寫工作啦~
#include<iostream>
#define LENGTH 10
using namespace std;
class Vector
{
private :
int x,y;
public :
Vector (){x=y=
0 ;}
void setX(
int x){
this ->x=x;}
void setY(
int y){
this ->y=y;}
int getX(){
return x;}
int getY(){
return y;}
void setUp(){setX(-
1 );setY(
0 );}
void setDown(){setX(
1 );setY(
0 );}
void setLeft(){setX(
0 );setY(-
1 );}
void setRight(){setX(
0 );setY(
1 );}
bool operator ==(Vector v){
return getX()==v.getX() && getY()==v.getY();}
void output(){cout<<
"(" <<getX()<<
"," <<getY()<<
")" <<endl;}
};class Cat
{
private :Vector position;Vector direction;
public :
Cat (){position.setX(
0 );position.setY(
0 );direction.setUp();}
void setPosition(Vector position){
this ->position=position;}Vector getDirection(){
return direction;}Vector getPosition(){
return position;}
void turnRight(){
if (direction.getX()==-
1 && direction.getY()==
0 ) direction.setRight();
else if (direction.getX()==
1 && direction.getY()==
0 ) direction.setLeft();
else if (direction.getX()==
0 && direction.getY()==-
1 ) direction.setUp();
else if (direction.getX()==
0 && direction.getY()==
1 ) direction.setDown();
else return ;}Vector getNextPosition(){Vector newVector;newVector.setX(position.getX()+direction.getX());newVector.setY(position.getY()+direction.getY());
return newVector;}
};class Mouse:
public Cat
{
public :
Mouse ():
Cat (){;}
};class Labyrinth
{
private :
char lab[LENGTH][LENGTH];Cat tom;Mouse jerry;
public :
void read (){
int i,j;
char tpchar;Vector position;
for (i=
0 ;i<LENGTH;i++){
for (j=
0 ;j<LENGTH;j++){cin>>tpchar;
if (tpchar==
'C' ){lab[i][j]=
'.' ;position.setX(i);position.setY(j);tom.setPosition(position);}
else if (tpchar==
'M' ){lab[i][j]=
'.' ;position.setX(i);position.setY(j);jerry.setPosition(position);}
else lab[i][j]=tpchar;}}}
bool legal(Vector position){
if ( position.getX()<
0 || position.getX()>=LENGTH|| position.getY()<
0 || position.getY()>=LENGTH|| lab[position.getX()][position.getY()]==
'*' )
return false ;
return true ;}
int getDirectionId(Vector direction){
if (direction.getX()==-
1 && direction.getY()==
0 )
return 0 ;
else if (direction.getX()==
1 && direction.getY()==
0 )
return 1 ;
else if (direction.getX()==
0 && direction.getY()==-
1 )
return 2 ;
else if (direction.getX()==
0 && direction.getY()==
1 )
return 3 ;
else return -
1 ;}
bool isVisited(unsigned
short visited[LENGTH][LENGTH][LENGTH][LENGTH]){
int mouseDirection=getDirectionId(jerry.getDirection());
int catDirection=getDirectionId(tom.getDirection());
int bit=catDirection*
4 +mouseDirection;
int element=visited[tom.getPosition().getX()][tom.getPosition().getY()][jerry.getPosition().getX()][jerry.getPosition().getY()];
int bitElement=(element>>bit)%
2 ;
if (bitElement==
1 )
return true ;
else {visited[tom.getPosition().getX()][tom.getPosition().getY()][jerry.getPosition().getX()][jerry.getPosition().getY()]+=(
1 <<bit);
return false ;}}
int run(){
int cnt=
0 ;unsigned
short visited[LENGTH][LENGTH][LENGTH][LENGTH]={
0 };
while (
true ){
if (tom.getPosition()==jerry.getPosition())
return cnt;
if (isVisited(visited))
return -
1 ;
if (!legal(tom.getNextPosition()))tom.turnRight();
else tom.setPosition(tom.getNextPosition());
if (!legal(jerry.getNextPosition()))jerry.turnRight();
else jerry.setPosition(jerry.getNextPosition());cnt++;}
return -
1 ;}
};
int main()
{Labyrinth lab;lab.read();cout<<lab.run()<<endl;
return 0 ;
}
最后我們進行一個小結(jié): 淺談ACM盲區(qū): 1.界面友好 2.編程規(guī)范 (1)變量和函數(shù)的命名規(guī)范 (2)變量和函數(shù)的命名格式(駝峰式) (3)縮進 (4)注釋:盡量用英文來保證兼容性 (5)可移植性、函數(shù)封裝與模塊耦合 3.非實用方法 4.實用性編程 5.面向?qū)ο缶幊?/p>
總結(jié)
以上是生活随笔 為你收集整理的essay 浅谈ACM盲区(下) 的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔 推薦給好友。