c++三大特性(繼承,封裝,多型)及過載與多型的區別。
封裝可以隱藏實現細節,使得程式碼模組化,繼承可以擴充套件已存在的模組,它們目的都是為了:程式碼重用。而多型是為了實現另一個目的:介面重用。
封裝是面向物件的特徵之一,是物件和類概念的主要特性。封裝是把過程和資料包圍起來,對資料的訪問只能通過已定義的介面。面向物件計算始於這個基本概念,即現實世界可以被描繪成一系列完全自治、封裝的物件,這些物件通過一個受保護的介面訪問其他物件。一旦定義了一個物件的特性,則有必要決定這些特性的可見性。
封裝:是指隱藏物件的屬性和實現細節,僅對外提供公共訪問方式。
封裝好處:
1.將變化隔離;
2.便於使用。
3.提高重用性。
4.提高安全性。
封裝原則:
將不需要對外提供的內容都隱藏起來。
把屬性都隱藏,提供公共方法對其訪問。
我們可以通過封裝使一部分成員充當類與外部的介面,而將其它的成員隱藏起來,這樣就限制了外部對成員的訪問,也使不同類之間的相互影響度降低
繼承優點:
1,提高了程式碼的複用性。
2,讓類與類之間產生了關係。有了這個關係,才有了多型的特性。
1,多型的體現
父類的引用指向了自己的子類物件。
父類的引用也可以接收自己的子類物件。
2,多型的前提
必須是類與類之間有關係。要麼繼承,要麼實現。
通常還有一個前提:存在覆蓋。
3,多型的好處
多型的出現大大的提高程式的擴充套件性。
4,多型的弊端
提高了擴充套件性,但是隻能使用父類的引用訪問父類中的成員。
過載,是指允許存在多個同名方法,而這些方法的引數不同。過載的實現是:編譯器根據方法不同的引數表
,對同名方法的名稱做修飾。對於編譯器而言,這些同名方法就成了不同的方法。它們的呼叫地址在編譯期
就綁定了。
C++, 子類中若有同名函式則隱藏父類的其他同名函式,即子類如果有同名函式則不能繼承父類的過載。
過載,是在編譯階段 便已確定具體的程式碼。對同名不同引數的 方法的呼叫。
多型:是指子類重新定義父類的虛方法(virtual,abstract)。當子類重新定義了父類的虛方法後,父類根據
賦給它的不同的子類,動態呼叫屬於子類的該方法,這樣的方法呼叫在編譯期間是無法確定的
是指子類重新定義父類的虛方法(virtual,abstract)。當子類重新定義了父類的虛方法後,父類根據
賦給它的不同的子類,動態呼叫屬於子類的該方法,這樣的方法呼叫在編譯期間是無法確定的。
而對於多型,只有等到方法呼叫的那一刻,編譯器才會確定所要呼叫的具體方法,這稱為“晚繫結”或“動態繫結”。
對於過載而言,在方法呼叫之前,編譯器就已經確定了所要呼叫的方法,這稱為“早繫結”或“靜態繫結”;
,封裝可以使得程式碼模組化,繼承可以擴充套件已存在的程式碼,他們的目的都是為了程式碼重用。而多型的目的則是為了介面重用。也就是說,不論傳遞過來的究竟是那個類的物件,函式都能夠通過同一個介面呼叫到適應各自物件的實現方法。
簡而言之:
- 有virtual才可能發生動態多型現象
- (無virtual)呼叫就按原型別呼叫
令人迷惑的隱藏規則
隱藏是指派生類的函式遮蔽了與其同名的基類函式,規則如下:
- 如果派生類的函式與基類的函式同名,但是引數不同。此時,不論有無virtual關鍵字,基類的函式將被隱藏(注意別與過載混淆,過載是在同一個類中,而隱藏涉及派生類與基類)。
- 如果派生類的函式與基類的函式同名,並且引數也相同,但是基類函式沒有virtual關鍵字。此時,基類的函式被隱藏(注意別與覆蓋混淆,覆蓋有virtual關鍵字)。
-
令人迷惑的隱藏規則
隱藏是指派生類的函式遮蔽了與其同名的基類函式,規則如下:
- 如果派生類的函式與基類的函式同名,但是引數不同。此時,不論有無virtual關鍵字,基類的函式將被隱藏(注意別與過載混淆,過載是在同一個類中,而隱藏涉及派生類與基類)。
- 如果派生類的函式與基類的函式同名,並且引數也相同,但是基類函式沒有virtual關鍵字。此時,基類的函式被隱藏(注意別與覆蓋混淆,覆蓋有virtual關鍵字)
-
C++虛擬函式
虛擬函式: 就是允許被其子類重新定義的成員函式,子類重新定義父類虛擬函式的做法,可實現成員函式的動態覆蓋(Override)。
純虛擬函式: 是在基類中宣告的虛擬函式,它在基類中沒有定義,但要求任何派生類都要定義自己的實現方法。在基類中實現純虛擬函式的方法是在函式原型後加“=0”
virtual void funtion()=0
抽象類: 包含純虛擬函式的類稱為抽象類。由於抽象類包含了沒有定義的純虛擬函式,所以不能進行例項化。
純虛擬函式的作用:
- 為了方便使用多型特性,我們常常需要在基類中定義虛擬函式。
- 在很多情況下,基類本身生成物件是不合情理的。例如,動物作為一個基類可以派生出老虎、孔雀等子類,但動物本身生成物件明顯不合常理。
為了解決上述問題,引入了純虛擬函式的概念,將函式定義為純虛擬函式(方法:virtual ReturnType Function()= 0;
),則編譯器要求在派生類中必須予以重寫以實現多型性。同時含有純虛擬函式的類稱為抽象類,它不能生成物件。這樣就很好地解決了上述兩個問題。