亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > 綜合 > 正文

面向對象編程,我的思想[下]

2024-07-21 02:04:03
字體:
來源:轉載
供稿:網友
2.3深入探討函數:

2.3.1構造函數、默認構造函數、 缺省構造函數

       對于上面的實例,它已經能完成絕大部分工作了,但它還是不完善的,還有許許多多的細節等到我們去完善!也許有的同學已經注意到了,當我創建完“jingwei”這個對象時,這個對象的所有的屬性都是空的,也就是說:這個對象的姓名是未定的、年齡是未定的、性別是未定的、薪水是未定的、午餐也是未定的。而我們想把這些屬性都添加上去,就還要用對象調用相應的方法,去一個個修改!天啊,這簡直是太麻煩了!有沒有什么好方法能夠在我們創建對象的同時就完成了對屬性賦值的操作呢?哦不,應該說是對屬性的初始化呢?當然沒問題了,這就需要所謂的構造函數!

       構造函數是類中最特殊的函數,它與析構函數的功能正好相反!

              從特征上來說:1.它是編程語言中唯一沒有返回值類型的函數。

                                     2.它的名稱與類的名稱必須要完全相同。

                                     3.它必須被聲明為公共(public)的類型

                                     4,可以對構造函數進行重載。

                                     5.它在創建對象是自動被調用。

              從功能上來說:1.它是對類中的屬性進行初始化。

其實,對于上面的程序來說我們沒有自己定義構造函數。但是,在這種情況下,系統會自動為我們定義一個“默認構造函數”。他會把數值變量自動賦值為0,把布爾行變量賦值為false等等(但在C++中,默認構造函數不初始化其成員)。如果程序員定義了構造函數,那么系統就不會再為你的程序添加一個缺默認造函數了。(在這里,我們提倡的是自己定義構造函數,而不是用系統的默認構造函數

       還是看個實例吧!這樣比較清楚一些!

       //employee.java

public class employee{

       private String name;       //員工姓名

       private int age;           //員工年齡

       private char sex;          //員工性別

       private float emolument;   //員工薪水

private boolean lunch;     //員工午餐

                              //……等等

       public employee(){        //這個就是“默認”構造函數

              name = “jw”;         //設置員工姓名

              age = 20;             //設置員工年齡

              sex = “M”;           //設置員工性別

              emolument = 100;     //設置員工薪水

              lunch = false;         //設置員工午餐

}

public void heater(){        //這個方法是用來加工員工的午餐

       lunch = true;

}

//……等等

};

這樣,在我們創建“jingwei”這個對象的同時,它的所有的屬性也被初始化了!顯然,這大大的提高了工作效率,但是,它還是不符合要求。想想看,如果我們現在創建這個類型的第二個對象的時候會發生什么事情?告訴你,除了對象的“名”(這個名稱不在是對象屬性中的名稱,而是對象本身的名稱)不一樣外,其所有的“屬性值”都一樣!比如:現在我們創建第二個對象flashmagic,然而我會發現這個對象的所有的屬性和jingwei這個對象的所有的屬性完全相同。而我們只能在用對象的方法去改變著寫屬性了!很顯然,這種方法不大好!我們需要一種方法在創建對象的時候為對象的屬性賦予“我們想要的值”。

相信你也看到了,默認構造函數就顯得無能為力了。我們需要的是帶參數的構造函數,在創建對象時,我們把參數傳給構造函數,這樣就能完成了上述的功能!口說無憑,還是來看個實例吧:

//employee.java

public class employee{

       private String name;       //員工姓名

       private int age;           //員工年齡

       private char sex;          //員工性別

       private float emolument;   //員工薪水

private boolean lunch;     //員工午餐

                              //……等等

       public employee(String n,int a,char s,float e,boolean l){ //看這個構造函數

              name = n;         //設置員工姓名

              age = a;          //設置員工年齡

              sex = s;          //設置員工性別

              emolument = e;    //設置員工薪水

              lunch =l;          //設置員工午餐

}


public void heater(){        //這個方法是用來加工員工的午餐

       lunch = true;

}

//……等等

};

這樣一來,在創建對象的同時我們就可以給他賦予我們想要的值,很顯然,這可就方便多了。哦,對了!還沒有告訴你怎么創建呢!哈哈,往前翻幾頁你會看到這句話:

jingwei = new employee();這是創建一個對象,而我們把它改成

jingwei = new employee("jingwei",20,'M',100,false);這樣一來,所有的工作都完成了,呵呵!(在創建對象的同時賦予了我們想要的“初值”)

2.3.2重載構造函數:

       我還是先把概念給你吧,讓你有個認識,隨后我們在進行論述。

       在JAVA中:

1.       函數重載是一個類中聲明了多個同名的方法,但有不同的參數個數和參數類型。

2.       函數重構是指在子類中聲明與父類同名的方法,從而覆蓋了父類的方法。重構解決了子類與父類的差異問題。(在討論到繼承時我會詳細說明)

       在C++中:

1.  數重載的概念一樣。

2.  重構的概念可就不一樣了,C++中功能更為龐大的虛函數。更詳細內容這里就不過多介紹了!

其實關于重載的概念你并不陌生,在編程中相信你也接觸過。呵呵!讓我們來舉個操作符重載的例子你就會明白了,(JAVA中不支持這個功能)我們定義三個整數變量:

int i1=2, i2=3,i3=0;

i3 = i1 + i2; 

此時i3=5;加號實現了兩個數相加的運算功能。然而我們現在要定義三個字符串變量:

       String str1=”jing”, str2=”wei”,str3=””;

       str3 = str1 + str2;

此時str3 = “jingwei”;加號實現了兩個字符串相加的運算功能。同樣是加號,既可以把兩個整型的變量加在一起,也可以把兩個字符串類型的變量加在一起。同一個操作符實現了不同的功能------這就是所謂的操作符重載(嘿嘿,我說你一定見過吧:)!不就好像是漢語中的一詞多意一樣!我需要說明一下的是,C++中的操作符重載可沒有這么簡單。比如,我們可以對兩個自定義類型的對象進行相加的運算,進行賦值的運算。這樣書寫簡潔明了,而且非常實用。當然,關于操作符重載的話題太多了,有興趣再看看書吧!

我們把操作符的話題在轉到函數上來,我們一直強調的是“對象調方法”------對象其實調的是方法的“名稱”。而我們現在要對方法進想重載,也就是定義多個相同名稱的函數,這樣計算機在調用的時候不會混淆嘛?我想應該不會的,呵呵,因為僅僅是函數名稱相同,而我們在調用函數時會把參數傳遞給他的。既是沒有參數也是一種參數傳遞參數的信息(信息為無參數)!然而由于參數類型、參數數量、返回值類型不同我們就可以對相同名稱的函數進行區分了!目的只有一個,用簡便的方法實現更多的功能。還是舉個例子吧,重載構造函數!

public class employee{

       public employee(String n,int a,char s,float e,boolean l){ //看這個構造函數

              name = n;         //設置員工姓名

              age = a;          //設置員工年齡

              sex = s;          //設置員工性別

              emolument = e;    //設置員工薪水

              lunch =l;          //設置員工午餐

}

 

public employee(){   //請注意這個函數沒有參數

       name = “jw”;

       age = 20;

       sex = ’W’;

       emolument = 99;

       lunch = true

}

//……等等

};

 
看,在一個類中有兩個名稱相同的函數,可我們在使用的時候系統如何知道我們調用的是那個版本的函數呢?呵呵,我剛剛說過了,可以通過函數的參數類型、參數數量、返回值類型來確定。現在我們接著試驗,我們創建兩個對象其中的一個調用帶參數的構造函數,第二個對象調用缺省值的構造函數。我們來看看結果:

jingwei = new employee("jingwei",20,'M',100,false);/*創建這個對象的時候調用的是帶參數的構造函數*/

flashmagic = new employee();//創建這個對象是調用的是卻省值的構造函數

而得到的結果呢?讓我們一起來看一看!

Jingwei這個對象中:                    flashmagic這個對象中:

name        jingwei                     name           jw

age          20                         age            20

sex          M                         sex             W

emolument   100                        emolument       99

lunch        false                       lunch           true

看,雖然是兩個名稱完全相同的函數,但完成了不同的工作內容。呵呵!關于函數重載我們就料到這里吧,我相信你已經有個大印象了,而更詳細的內容仍需要你的努力!

重載普通的函數與重載構造函數大同小異,不過他多了一個this指針!this一般是對當前對象的引用。這么說吧,如果涉及到兩個以上的對象時就會使用this指針。每個成員函數都有一個this指針,它是一個隱藏的參數,this指針只向調用它的對象!我說過方法只有一份,而對象都有自己的屬性,當對象調用方法來先是屬性的時候,他怎么來判斷調用的時不是自己的屬性呢?這就需要this指針來大顯神威了。

關于拷貝構造函數、內聯函數、虛函數、模版等歐就不做過多的討論了,因為JAVA中好像沒有這些了。不過我需要提醒你一下的是,在C++中,類內定義的函數自動轉換為內聯函數,而這好像與我前面提到的思想有沖突。因為內聯函數的目的是減少函數調用的開銷!呵呵!我也沒繞出來呢!還請哪為大蝦指點一二!謝!

2.3.3 初始化與賦值

這里我卻要提醒你一下的是,初始化與賦值是完全不同的兩個概念。創建一個類的時候會調用這個類的構造函數對對象的屬性進行初始化。而如果以后再把這個對象賦給其他同類型的對象時可就沒那么簡單了。在JAVA中直接賦值就行了,因為JAVA中取消了指針,不存在指針的深拷貝與前拷貝問題。而在C++中就需要拷貝構造函數以及操作符重載了。因為JAVA中不牽扯這些東西,所以偶就不做過多介紹了。詳情請參閱相關書籍吧!

2.3.4析構函數:

JAVA中不再支持指針了,所以你感覺不到它的重要性,因為系統會自動為你釋放內存。而在C++中一切都是手動的。在構造函數中new了一個指針,在析夠函數中就要delete這個指針。

2.3.5靜態:

現在我們再來看一看“靜態”是咋一回事兒!

把一個變量或函數聲明為靜態的需要“static”這個關鍵字。聲明靜態的目的是“為某個類的所有對象的某個屬性或方法分配單一的存儲空間”。靜態的數據是屬于類的,不屬于任何的對象。靜態的數據在聲明的時候系統就為他分配了內存空間,而不用等到創建對象時。舉個例子來幫你更好的理解它吧。

還是接著上面的例子。還記得剛剛我說過的員工能用微波爐熱飯的事情吧?,F在我們要找一個手套,畢竟想把熱好的飯從微波爐里拿出來直接下手是不行的。我把手套定義成一個布爾型的變量,它有干凈和臟兩種狀態。想想看手套是屬于誰的?所有對象?不對!因為只有方法才能屬于所有的對象。它是屬于類的,它像微波爐那個方法一樣,在內存中只有一份,所有的對象通過方法都能夠修改它。而下一次修改是基于上一次修改的基礎之上的!我的意思是:一個員工把手套弄臟了,下一個員工在使用的時候它還是臟的。而這個員工把手套洗干凈之后,別人再用的時候它就是干凈的了!就這么點事兒,明白了吧!

關于靜態函數我想就沒什么可多說的了。給我的感覺就是,它也是屬于類的,在定義的時候就分配的內存。調用是可以使用類名直接調用。其他的和普通成員函數沒什么不同的了不過這里需要說明的一點是:在JAVA中,靜態的成員函數只能修改靜態的屬性,而靜態的屬性可以被所有的成員函數修改。不過在C++中就沒這么多事兒了!

2.4繼承

繼承很好理解,它的最大好處就是“代碼重用”,大大提高了工作效率。舉個例子你就明白了。世界上先有的黑白電視機,它有自己的工作原理。然而人們在他的基礎之上開發出了彩色電視機。彩色電視機繼承了黑白電視機的所有的特性與方法!因為它既能顯示彩色圖像也能顯示黑白圖像。然而它與黑白電視機又有許多區別,在工作原理上。彩色電視及多了矩陣色電路,把彩色信號分離出三種顏色(RGB),他就能顯示彩色的圖像了。而黑白電視機沒有這塊電路,即使它收到了彩色信號也顯示不了彩色圖像。彩色電視機是從黑白電視機中派生出來的。所以,黑白電視機是父類,彩色電視既是子類,彩色電視繼承了黑白電視機所有的特性與方法。看看再計算機中它是什么樣子的吧:

//BWtv.java               父類的定義

public class BWtv{

       private int a;

       public BWtv(){

              a=1;

       }

       public changeBWtv(int i){

              a=i;

}

}

//Ctv.java                子類的定義

class Ctv exntends BWtv{        //注意關鍵字“extends”

       private int b;

       public Ctv(){

              b=2;

       }

       public changetCv(int x){

              b = x;

       }

}

有了上面的定義,我們來看看他們都有什么數據。

BWtv的數據包括                         Ctv的數據包括

 private int a                               private int a

                                                                        private int b

 public changeBWtv();                       public changeBWtv()

                                                                        public changeCtv();

你看,子類擁有父類的所有的方法及屬性。注意關鍵字”extends”,它的意思是繼承。在C++中使用的是“:”操作符。意思是一樣的。但是這里有許多問題,首先是訪問權限的問題,子類的對象擁有父類的所有的屬性和方法這句話。對嘛?肯定是對的!(不過JAVA的書中可不是這么說的,他說只繼承非private類型的屬性及方法,我覺得它這句話有錯誤?。┛墒牵宇惖膶ο蟛荒苤苯釉L問父類的私有屬性或方法,它只能通過父類的公有成員函數來訪問。而此時,如果你修改了父類的屬性的值。那就真的修改了。我的意思是:父類的私有屬性的值會隨著子類對象調用父類的公有方法進行對相應屬性的修改而發生變化!(這里面存在一個域的問題,所有的修改都是在子類中進行的,修改的是子類繼承的父類的屬性在子類這個域中,此時父類以拷貝到子類中了。)。程序中定義的父類的屬性不會發生任何變化在父類的域中),)

       其次是構造函數,在創建一個子類對象時首先要調用的是父類的構造函數,然后再調用子類的構造函數,畢竟,子類的構造函數不包括父類的屬性的初始化功能!從這一點來說我的觀點又是正確的子類的對象擁有父類的所有的屬性和方法”)當然了,析夠函數的調用順序正好相反!

       現在讓我們來談談protected這個關鍵字吧,它的意思是:對對象來說,聲明為protected的變量是私有的,而對子類父類來說,聲明為protected的變量是公共的。

       現在又出現了這樣的一個問題,如果我們在子類中也定義了一個int 類型的變量a,那我們在創建子類的對象的時候調用的是子類定義的還是父類定義的呢?這就涉及到數據的隱藏的問題了,我可以告訴你肯定是調用的子類的變量a。因為,子類把父類的這個同名變量給隱藏了。而如果是方法呢?這就涉及到重構的問題了,在上面我提到過“函數重構是指在子類中聲明與父類同名的方法,從而覆蓋了父類的方法。重構解決了子類與父類的差異問題。”這里必須要聲明一下的是,在JAVA中,子類出現了對父類屬性的隱藏和父類方法的覆蓋后,在子類中,子類對象僅能調用子類本身的屬性和方法。要調用父類的屬性和方法必須要實用super這個關鍵子。而在C++中就不這樣了。因為它有虛函數

虛擬函數在C++中非常好玩的事。我們可以把需要改寫的函數聲明為虛函數,用virtual這個關鍵字來聲明。這樣。假如如果我們CwinApp這么一個基類,它里面定義了一個成員(虛)函數為InitInstance()和另一個為(虛)函數InitApplication()。如果我從CWinApp派生一個子類為CMyWinApp并修改了InitInstance()這個成員函數。我們并沒有修改InitApplication()這個成員函數?,F在我們創建CMyWinApp這個類的函數theApp,我們并創建一個指針*pApp指向這個對象theApp。此時:

pApp->InitInstance()     //指針調用的是子類CMyWinApp的虛方法

pApp->InitApplication()  //指針調用的時父類CwinApp的虛方法

因為子類并沒有修改父類的方法,所以調用的是父類的虛方法。這就牽扯到虛你表的問題。礙與本篇文章的定位,這里就不討論了!

關于父類與子類的對象的類型轉換問題是這樣的,子類對象轉換為父類對象時,不會出現錯誤。因為子類包含父類的所有的屬性及方法,而父類向子類轉換時就難說了,呵呵。這還會牽扯到虛擬表的問題,也不討論了!

       JAVA中不再支持多重繼承,也就是一個類從兩個以上的類中繼承而來,但它卻多了接口的概念“interface”。這里就不做過多介紹了!

       關于抽象基類也沒什么難的!他的一個大概念就是:做為許多類的父類,不定義對象,只做派生用!

我能做得也只有這些了,如果你能明白以上的六七成,那就是對我最大的回報了,呵呵!就像剛剛開始我說的,我只是給你一個大概的思想,至于內部的實現細節,仍需要你的繼續努力。關于編程語言的內容還有許多許多,實屬小生個人能力有限而不能全盤照顧到。不過作為一個初學者的你來說,這些東西都是基本的。需要我提醒你一點的是,不要指望在第一、二遍的時候看懂什么!加油:)


                                                                                                         04.4.29  韓景維

愿意和大家保持聯絡,如果大家能夠對本篇文章提出寶貴的意見和建議,我將不勝感激。我的電子郵件地址是:

onegenius@126.com

或在QQ里給我留言(86228551---亂碼游魂.h)
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
丰满岳妇乱一区二区三区| 精品国产一区二区三区久久久| 亚洲永久免费观看| 亚洲国产成人精品电影| 亚洲精品国产精品乱码不99按摩| 欧美极品少妇与黑人| 亚洲人成网站在线播| 97精品一区二区视频在线观看| 国产精品久久久精品| 成人免费高清完整版在线观看| 最近2019中文免费高清视频观看www99| 久久精品国亚洲| 日韩在线小视频| 亚洲成人免费网站| 亚洲视频一区二区| 在线观看国产精品日韩av| 久久久免费在线观看| 亚洲sss综合天堂久久| 亚洲综合中文字幕在线观看| 午夜精品一区二区三区在线播放| 在线播放精品一区二区三区| 国产精品美女999| 欧美在线视频免费| 中文字幕一精品亚洲无线一区| 日韩av一区二区在线| 亚洲xxxxx电影| 亚洲精选在线观看| 久久久人成影片一区二区三区观看| 最近免费中文字幕视频2019| 91精品国产电影| 都市激情亚洲色图| 中文字幕视频在线免费欧美日韩综合在线看| 91久久精品一区| 亚洲人成网站777色婷婷| 亚洲欧美日韩中文在线制服| 国产成人精品日本亚洲| 欧美又大粗又爽又黄大片视频| 91九色国产视频| 欧美xxxx做受欧美.88| 欧美特黄级在线| 久久视频在线直播| 久久精品视频va| 国产成人综合精品| 久久精品99无色码中文字幕| 亚洲最新av在线网站| 国产精品欧美激情| 欧美国产日韩xxxxx| 亚洲美女福利视频网站| 欧美激情日韩图片| 欧美亚洲另类视频| 大荫蒂欧美视频另类xxxx| 欧美日韩福利视频| 亚洲精品第一页| 在线视频日韩精品| 国产成人黄色av| 欧美日韩国产精品| 久久精品男人天堂| 成人中文字幕在线观看| 亚洲xxxxx性| 欧美视频在线观看 亚洲欧| 成人免费观看49www在线观看| 日韩欧美亚洲国产一区| 国产精品一二三在线| 日韩精品欧美国产精品忘忧草| 久久综合免费视频| 欧美性猛交丰臀xxxxx网站| 欧美激情伊人电影| 97激碰免费视频| 国产剧情久久久久久| 九九热最新视频//这里只有精品| 日本免费一区二区三区视频观看| 国内精品小视频| 久久av资源网站| 欧美乱大交xxxxx另类电影| 国产在线观看精品一区二区三区| 亚洲人免费视频| 91久久精品久久国产性色也91| 日韩精品福利网站| 1769国内精品视频在线播放| 欧美大片在线影院| 国产精品视频在线观看| 久久夜色精品国产欧美乱| 亚洲第一色中文字幕| 欧美日韩亚洲一区二区| 欧美性极品少妇精品网站| 国产精品久久视频| 伊人伊人伊人久久| 97免费视频在线播放| 美日韩精品免费观看视频| 国内精品400部情侣激情| 91精品在线观看视频| 日韩欧美999| 国产欧美精品在线播放| 国产精品自拍偷拍| 国产亚洲精品久久久久久777| 成人性生交大片免费看小说| 欧美日韩国产综合视频在线观看中文| 国产欧美日韩专区发布| 久久精品国产2020观看福利| 高清欧美电影在线| 久久伊人免费视频| 国产主播精品在线| 欧美老女人性生活| 日本不卡免费高清视频| 国自产精品手机在线观看视频| 亚洲日韩欧美视频| 2023亚洲男人天堂| 欧美日韩中文字幕在线视频| 欧美成人精品在线观看| 欧美成人第一页| 国产精品久久久久不卡| 精品视频www| 全亚洲最色的网站在线观看| 亚洲视频999| 久久久99免费视频| 欧美日本高清一区| 国产精品jizz在线观看麻豆| 久久久久久亚洲精品中文字幕| 精品日韩美女的视频高清| 久久视频这里只有精品| 日韩精品中文字幕在线| 国产亚洲人成网站在线观看| 国产丝袜精品视频| 日韩天堂在线视频| 国产精品久久久久高潮| 国产精品视频xxx| 亚洲自拍偷拍第一页| 国产在线视频欧美| 欧美黑人视频一区| 国内精品一区二区三区四区| 日韩av影视在线| 国模私拍一区二区三区| 中文字幕久热精品视频在线| 久久久久久久国产精品视频| 日韩av黄色在线观看| 色阁综合伊人av| 91精品国产91久久久| 欧美日韩激情小视频| 欧美不卡视频一区发布| 亚洲人成亚洲人成在线观看| 精品美女国产在线| 欧美色videos| 久久不射电影网| 亚洲黄色在线看| 亚洲欧美日本另类| 亚洲欧美自拍一区| 欧美一区三区三区高中清蜜桃| 国内精品400部情侣激情| 奇米成人av国产一区二区三区| 在线一区二区日韩| 孩xxxx性bbbb欧美| 欧美中文字幕第一页| 欧美黄色成人网| 国产黑人绿帽在线第一区| 久久久久这里只有精品| 日韩在线观看av| 欧美大片欧美激情性色a∨久久| 久久久久久国产精品三级玉女聊斋| 欧美日韩免费看| 欧洲亚洲免费在线| 中文字幕日韩在线播放| 亚洲天堂免费观看| 日韩av中文在线| 欧美性猛交xxxxx免费看|