導航:首頁 > 源碼編譯 > 編譯時多態性可通過什麼實現

編譯時多態性可通過什麼實現

發布時間:2022-04-27 07:09:16

1. 簡述c#繼承和多態的含義及其實現方法

一、封裝:
封裝是實現面向對象程序設計的第一步,封裝就是將數據或函數等集合在一個個的單元中(我們稱之為類)。被封裝的對象通常被稱為抽象數據類型。
封裝的意義:
封裝的意義在於保護或者防止代碼(數據)被我們無意中破壞。在面向對象程序設計中數據被看作是一個中心的元素並且和使用它的函數結合的很密切,從而保護它不被其它的函數意外的修改。
封裝提供了一個有效的途徑來保護數據不被意外的破壞。相比我們將數據(用域來實現)在程序中定義為公用的(public)我們將它們(fields)定義為私有的(privat)在很多方面會更好。私有的數據可以用兩種方式來間接的控制。第一種方法,我們使用傳統的存、取方法。第二種方法我們用屬性(property)。
使用屬性不僅可以控制存取數據的合法性,同時也提供了「讀寫」、「只讀」、「只寫」靈活的操作方法。
訪問修飾符:
Private:只有類本身能存取.
Protected:類和派生類可以存取.
Internal:只有同一個項目中的類可以存取.
Protected Internal:是Protected和Internal的結合.
Public:完全存取.
二、繼承:
繼承主要實現重用代碼,節省開發時間。
1、C#中的繼承符合下列規則:
繼承是可傳遞的。如果C從B中派生,B又從A中派生,那麼C不僅繼承了B中聲明的成員,同樣也繼承了A中的成員。Object類作為所有類的基類。
派生類應當是對基類的擴展。派生類可以添加新的成員,但不能除去已經繼承的成員的定義。
構造函數和析構函數不能被繼承。除此之外的其它成員,不論對它們定義了怎樣的訪問方式,都能被繼承。基類中成員的訪問方式只能決定派生類能否訪問它們。
派生類如果定義了與繼承而來的成員同名的新成員,就可以覆蓋已繼承的成員。但這並不因為這派生類刪除了這些成員,只是不能再訪問這些成員。
類可以定義虛文法、虛屬性以及虛索引指示器,它的派生類能夠重載這些成員,從而實現類可以展示出多態性。
2、new關鍵字
如果父類中聲明了一個沒有friend修飾的protected或public方法,子類中也聲明了同名的方法。則用new可以隱藏父類中的方法。
3、base關鍵字
base 關鍵字用於從派生類中訪問基類的成員:
調用基類上已被其他方法重寫的方法。
指定創建派生類實例時應調用的基類構造函數。
三、多態
1、多態:同一操作作用於不同的對象,可以有不同的解釋,產生不同的執行結果。在運行時,可以通過指向基類的指針,來調用實現派生類中的方法。
編譯時的多態性:
編譯時的多態性是通過重載來實現的。對於非虛的成員來說,系統在編譯時,根據傳遞的參數、返回的類型等信息決定實現何種操作。

運行時的多態性:
運行時的多態性就是指直到系統運行時,才根據實際情況決定實現何種操作。C#中,運行時的多態性通過虛成員實現。

編譯時的多態性為我們提供了運行速度快的特點,而運行時的多態性則帶來了高度靈活和抽象的特點。
2、實現多態:
介面多態性。
繼承多態性。
通過抽象類實現的多態性。
3、override關鍵字:
重寫父類中的virtual修飾的方法,實現多態。

2. C++編程中多態性的實現機制到底是什麼呀

樓上的說不對
在C++中,多態性分為兩種,一種稱為編譯時多態,另一種為運行時多態
分別解釋下:
1.編譯時多態,也就是函數重載,所謂函數重載是指同一個函數名可以對應著多個函數的實現,具體調用哪個按照由參數個數,參數類型等來決定,這個簡單,就不說了
2.運行時多態,就是虛函數。
在定義了虛函數後,可以在基類的派生類中對虛函數重新定義,以實現你所想要的功能。

3. 什麼叫做多態性 在C++中是如何實現多態的

C++中的多態(雖然多態不是C++所特有的,但是C++中的多態確實是很特殊的)分為靜多態和動多態(也就是靜態綁定和動態綁定兩種現象),靜動的區別主要在於這種綁定發生在編譯期還是運行期,發生在編譯期的是靜態綁定,也就是靜多態;發生在運行期的則是動態綁定,也就是動多態。

靜多態可以通過模板和函數重載來實現(之所說C++中的多態主要還是因為模板這個東西),下面舉兩個例子:
1)函數模板
template <typename T>
T max(const T& lsh, const T& rhs)
{
return (lsh > rhs) ? lsh : rhs;
}
返回兩個任意類型對象的最大值(對象),前提是該類型能夠使用>運算符進行比較,並且返回值是bool類型。
使用:
int a = 3; int b = 4;
cout << max(a, b) << endl;
float c = 2.4; float d = 1.2;
cout << max(c, d) << endl;
輸出結果為:
4
2.4
這種綁定發生在編譯期,這是由於模板的實例化是發生在編譯期的,即在編譯時編譯器發現你調用max(a, b)時就自動生成一個函數
int max(const int& lsh, const int& rhs)
{
return (lsh > rhs) ? lsh : rhs;
}
即將所有的T替換成int;
當你調用max(c, d)時就自動生成一個函數
float max(const float& lsh, const float& rhs)
{
return (lsh > rhs) ? lsh : rhs;
}
之所以說開始的函數定義是函數模板,就是因為他就像個模子似的,你可以用鋁作為原料也可以用石膏或者銅。
2)函數重載:
int max (int a, int b)
{
return (a > b) ? a : b;
}
int max (int a, int b, int c)
{
return max(max(a, b), c);
}
兩個函數名稱一樣,參數類型或個數不完全相同,返回值一樣(這個不重要)。
使用:
int a = 3, b = 4, c = 5;
cout << max(a, b) << endl;
cout << max(a, b, c) << endl;
輸出結果為:
4
5
確定函數的過程也發生在編譯器,當你使用max(a, b),編譯器發現只有兩個參數,那麼就調用只有兩個參數的函數版本,當使用max(a, b, c)時,編譯器則使用有3個參數的版本。
通過上面的兩個例子,你還可以使用更為方便的模板函數重載:
template <typename T>
T max(const T& lsh, const T& rhs)
{
return (lsh > rhs) ? lsh : rhs;
}

template <typename T>
T max(const T& a, const T& b, const T& c)
{
return max(max(a, b), c);
}
使用
float a = 3.6, b = 1.2, c = 7.8;
cout << max(a, b, c) << endl;
輸出:
7.8
通過參數個數和類型,編譯器自動生成和調用對應得函數版本!

動多態則是通過繼承、虛函數(virtual)、指針來實現。
class A {
public:
virtual void func() const {
coust << 「A::func()」 << endl;
}
}

class B : public A {
public:
virtual void func() const {
coust << 「B::func()」 << endl;
}
}
使用:
A a* = B();
a->func();
輸出:
B::func()
編譯期是不調用任何函數的,編譯器編譯到a->func()時只是檢查有沒有語法問題,經過檢查沒有。編譯器並不知道調用的是A版本的func()還是B版本的func(),由於a是一個指向B對象的指針,所以a只知道它指向的是一個A類型(或者能轉換成A類型)的對象。通常集成體系就說明了(由於是公有繼承)B是一種A。在運行期,a要調用a所指向對象的func()函數,就對它指向的對象下達調用func()的命令,結果a所指向的是一個B對象,這個對象就調用了自己版本(B版)的func()函數,所以輸出時B::func()

總結:
在編譯期決定你應該調用哪個函數的行為是靜態綁定(static-binding),這種現象就是靜多態。
在運行期決定應該調用哪中類型對象的函數的行為是動態綁定(dynamic-binding),這種現象就是動多態!

註:由於這是我花了有限的時間總結的,語言應用能力比較差,還有比如類模板(靜多態和動多態組合的情況)都沒有說,最近比較忙,請見諒!

如果還不是很懂,我建議你看C++Primer 4th Edition,講的比較清晰,但是比較零散!

4. 編譯時的多態性和運行時的多態性在實現方法上有何不同

我不知道你哪本書上看到的,但是,只要不是後綁定就不能稱為多態,前綁定只能稱為代碼重用,比如函數的重載、覆蓋以及一般的類繼承。
多態的關鍵特點就是:在運行時虛基類指針指向派生類對象地址,而將派生類對象地址賦值給基類指針,這就是所謂的後綁定,編譯時綁定稱為前綁定,因此多態另一個特點就是「動態「。換句話說,如果是後綁定,編譯器事先是不知道在運行時指針將指向哪一種派生類的對象,因此基類指針必須是「虛「的,虛基類中不能有任何實現只有定義,此時虛基類的作用就是一個類介面,這樣才能在編譯時「模糊」掉類型匹配原則,基類的作用只是個約定,定義了函數調用格式,而只在運行時才確定指針具體指向哪一個對象。
而所謂編譯時的多態性根本不存在,如果編譯器能確定基類指針指向哪一個派生類對象地址,就不是多態,哪怕你採用重載覆蓋或者繼承,這些編譯器已經可以預知的事情,一旦編譯完成就固定了,運行時無法更改的,比如你不能在不重新編譯的情況下增加一個重載,這就制約了程序運行時的靈活性以及可擴充性。而多態完全可以實現「熱「更新,更多的是便於程序的可擴充性。你完全可以將派生類編譯在DLL中,每當更新程序時,只要替換掉DLL而不用重新編譯全部代碼。

5. C++多態是怎麼實現的

1、C++中,在調用重載函數時,能夠根據參數的類型及個數來找到確定的函數。然而,這一過程是通過編譯來完成的,也就是說,程序中尋找重載函數具體地址的工作是在程序編譯過程中完成的,程序一旦編譯完成,所有函數、方法等(包括重載函數、方法)的調用地址都已明確。
2、C++中,多態是運行時特徵,也就是說,程序實現多態是在程序運行的過程中來實現的。這一過程通常是針對虛擬類或方法來的,即在程序運行過程中動態的確定虛擬類或方法的地址,從而實現具體的類或方法的調用。
3、根據樓主的舉例,實現多態輸入,無非是希望程序在運行過程中,自動區分輸入內容的數據類型,此後程序根據具體的數據類型來調用相應的方法。由上述2所述,C++程序不具備針對變數的多態特性。因此,如果要實現這類「多態」,仍舊是程序員的職責,即程序員在代碼中來實現輸入的內容的具體數據類型。

6. C++語言中編譯時的多態性是通過____ _ ____實現的.空里填什麼呢

function checkName()
{
var flag=true;
var userName = $("#username").val();
if(chkNullOrEmp(userName))
{
$.ajax({
type : 'post',
url : '<%=basePath%>register/checkName.action?r='+Math.random(),
async: false,
data:"userbean.username="+encodeURI(encodeURI($.trim(userName))),
dataType : 'json',
success : function(json)
{
if(json.operFlag=='success')
{
if(json.count>0)
{
usermsg.innerHTML = "<font color='red'>" +"用戶名已存在!"+ "</font>";
flag=false;
}
usermsg.innerHTML = "<font color='green'>" +"恭喜您,用戶名可以使用!"+ "</font>";
}
else
{
alert("操作失敗");
flag=false;
}
},
error : function(error)
{
alert("操作失敗!");
flag=false;
}
});
}

if(flag)
{
return true;
}
else
{
$("#saveBnt").attr("disabled","");
return false;
}
}

function register(){
$("#saveBnt").attr("disabled",true);
if(checkData()&&checkName())
{
var username=$("#username").val();
var name = $("#userForm").find("input[id='username']").val();
var password = $("#userForm").find("input[id='password']").val();
var v_data = "userbean.username="+name+"&userbean.password="+password;
$.ajax({
type : 'post',
url : '<%=basePath%>register/addUser.action?r='+Math.random(),
data : v_data,
dataType : 'json',
async : false,
success : function(data){
if(data.operflag=="success")
{
alert("操作成功");
}
else
{
alert("操作失敗");
}

},
error :function(error) {
alert("操作失敗!");
}
});
}

}

function checkData()
{
var username = $("#userForm").find("input[id='username']").val();
var password = $("#userForm").find("input[id='password']").val();
var repassword = $("#userForm").find("input[id='repassword']").val();

if(!chkNullOrEmp(username))
{
alert("用戶名稱不能為空");
$("#saveBnt").attr("disabled","");
return false;
}

if(!chkNullOrEmp(password))
{
alert("密碼不能為空");
$("#saveBnt").attr("disabled","");
return false;
}

if(repassword!=password)
{
alert("兩次密碼不一致");
$("#saveBnt").attr("disabled","");
return false;
}
return true;
}

/**
*判斷是否為空
*/
function chkNullOrEmp(str)
{
if(str==null)
{
return false;
}
else
{
str = $.trim(str);
if(str.length>0)
{
return true;
}
else
{
return false;
}
}
}

7. java的多態怎麼實現

實現多態的三個條件(前提條件,向上轉型、向下轉型)
1、繼承的存在;(繼承是多態的基礎,沒有繼承就沒有多態)
2、子類重寫父類的方法。(多態下會調用子類重寫後的方法)
3、父類引用變數指向子類對象。(涉及子類到父類的類型轉換)
向上轉型 Student person = new Student()
將一個父類的引用指向一個子類對象,成為向上轉型,自動進行類型轉換。此時通過父類引用變數調用的方法是子類覆蓋或繼承父類的方法,而不是父類的方法此時通過父類引用變數無法調用子類特有的方法。
向下轉型 Student stu = (Student)person;
將一個指向子類對象的引用賦給一個子類的引用,成為向下轉型,此時必須進行強制類型轉換。向下轉型必須轉換為父類引用指向的真實子類類型,,否則將出現ClassCastException,不是任意的強制轉換
向下轉型時可以結合使用instanceof運算符進行強制類型轉換,比如出現轉換異常---ClassCastException

8. C++中多態是怎樣實現的

多態是一種不同的對象以單獨的方式作用於相同消息的能力,這個概念是從自然語言中引進的。例如,動詞「關閉」應用到不同的事務上其意思是不同的。關門,關閉銀行賬號或關閉一個程序的窗口都是不同的行為;其實際的意義取決於該動作所作用的對象。 大多數面向對象語言的多態特性都僅以虛擬函數的形式來實現,但C++除了一般的虛擬函數形式之外,還多了兩種靜態的(即編譯時的)多態機制: 2、模板:例如,當接受到相同的消息時,整型vector對象和串vector對象對消息反映是不同的,我們以關閉行為為例: vector < int > vi; vector < string > names; string name("VC知識庫"); vi.push_back( 5 ); // 在 vector 尾部添加整型 names.push_back (name); // 添加串和添加整型體現差別的潛在的操作 靜態的多態機制不會導致與虛擬函數相關的運行時開。此外,操作符重載和模板兩者是通用演算法最基本的東西,在STL中體現得尤為突出。 那麼接下來我們說說以虛函數形式多態: 通常都有以重載、覆蓋、隱藏來三中方式,三種方式的區別大家應該要很深入的了解,這里就不多說了。 許多開發人員往往將這種情況和C++的多態性搞混淆,下面我從兩方面為大家解說: 1、 編譯的角度 C++編譯器在編譯的時候,要確定每個對象調用的函數的地址,這稱為早期綁定(early binding)。2、 內存模型的角度為了確定對象調用的函數的地址,就要使用遲綁定(late binding)技術。當編譯器使用遲綁定時,就會在運行時再去確定對象的類型以及正確的調用函數。而要讓編譯器採用遲綁定,就要在基類中聲明函數時使用virtual關鍵字(注意,這是必須的,很多開發人員就是因為沒有使用虛函數而寫出很多錯誤的例子),這樣的函數我們稱為虛函數。一旦某個函數在基類中聲明為virtual,那麼在所有的派生類中該函數都是virtual,而不需要再顯式地聲明為virtual。 那麼如何定位虛表呢?編譯器另外還為每個類的對象提供了一個虛表指針(即vptr),這個指針指向了對象所屬類的虛表。在程序運行時,根據對象的類型去初始化vptr,從而讓vptr正確的指向所屬類的虛表,從而在調用虛函數時,就能夠找到正確的函數。 正是由於每個對象調用的虛函數都是通過虛表指針來索引的,也就決定了虛表指針的正確初始化是非常重要的。換句話說,在虛表指針沒有正確初始化之前,我們不能夠去調用虛函數。那麼虛表指針在什麼時候,或者說在什麼地方初始化呢? 答案是在構造函數中進行虛表的創建和虛表指針的初始化。還記得構造函數的調用順序嗎,在構造子類對象時,要先調用父類的構造函數,此時編譯器只「看到了」父類,並不知道後面是否後還有繼承者,它初始化父類對象的虛表指針,該虛表指針指向父類的虛表。當執行子類的構造函數時,子類對象的虛表指針被初始化,指向自身的虛表。 要注意:對於虛函數調用來說,每一個對象內部都有一個虛表指針,該虛表指針被初始化為本類的虛表。所以在程序中,不管你的對象類型如何轉換,但該對象內部的虛表指針是固定的,所以呢,才能實現動態的對象函數調用,這就是C++多態性實現的原理。總結(基類有虛函數):1、 每一個類都有虛表。2、虛表可以繼承,如果子類沒有重寫虛函數,那麼子類虛表中仍然會有該函數的地址,只不過這個地址指向的是基類的虛函數實現。如果基類3個虛函數,那麼基類的虛表中就有三項(虛函數地址),派生類也會有虛表,至少有三項,如果重寫了相應的虛函數,那麼虛表中的地址就會改變,指向自身的虛函數實現。如果派生類有自己的虛函數,那麼虛表中就會添加該項。3、派生類的虛表中虛函數地址的排列順序和基類的虛表中虛函數地址排列順序相同。

9. 編譯時多態性使用什麼獲得!A重載函數B繼承C虛函數D.B和C

函數重載和模板。就這題來說選A。
繼承和虛函數對應的多態需要在運行的時候才能確定具體對象,所以不屬於編譯時多態。

函數重載是讓一個函數名對應多個函數,編譯器會根據調用時候的特徵確定要調用的函數,不需要再運行時處理。
而模板是讓一個一個類型模板或者函數模板對應多個類型或者函數,編譯器根據對模板實例化是使用的參數生成具體的類和函數,也不是在運行時進行的。
另外注意模板變數不屬於多態范疇。

10. 什麼是多態

多態首先是建立在繼承的基礎上的,先有繼承才能有多態。多態是指不同的子類在繼承父類後分別都重寫覆蓋了父類的方法,即父類同一個方法,在繼承的子類中表現出不同的形式。多態成立的另一個條件是在創建子類時候必須使用父類new子類的方式。

多態(Polymorphism)按字面的意思就是「多種狀態」。在面向對象語言中,介面的多種不同的實現方式即為多態。引用Charlie Calverts對多態的描述——多態性是允許你將父對象設置成為一個或更多的他的子對象相等的技術,賦值之後,父對象就可以根據當前賦值給它的子對象的特性以不同的方式運作(摘自「Delphi4編程技術內幕」)。

簡單的說,就是一句話:允許將子類類型的指針賦值給父類類型的指針。多態性在Object Pascal和C++中都是通過虛函數實現的。

拓展資料:

多態指同一個實體同時具有多種形式。它是面向對象程序設計(OOP)的一個重要特徵。如果一個語言只支持類而不支持多態,只能說明它是基於對象的,而不是面向對象的。C++中的多態性具體體現在運行和編譯兩個方面。運行時多態是動態多態,其具體引用的對象在運行時才能確定。編譯時多態是靜態多態,在編譯時就可以確定對象使用的形式。

多態:同一操作作用於不同的對象,可以有不同的解釋,產生不同的執行結果。在運行時,可以通過指向基類的指針,來調用實現派生類中的方法。

C++中,實現多態有以下方法:虛函數,抽象類,覆蓋,模板(重載和多態無關)。

OC中的多態:不同對象對同一消息的不同響應.子類可以重寫父類的方法。

多態就是允許方法重名 參數或返回值可以是父類型傳入或返回。

多態也指生物學中腔腸動物的特殊的生活方式。水螅態與水母態的世代交替現象。

把不同的子類對象都當作父類來看,可以屏蔽不同子類對象之間的差異,寫出通用的代碼,做出通用的編程,以適應需求的不斷變化。

賦值之後,父類型的引用就可以根據當前賦值給它的子對象的特性以不同的方式運作。也就是說,父親的行為像兒子,而不是兒子的行為像父親。

使用繼承性的結果就是當創建了一個類的家族,在認識這個類的家族時,就是把子類的對象當作基類的對象,這種認識又叫作upcasting(向上轉型)。這樣認識的重要性在於:我們可以只針對基類寫出一段程序,但它可以適應於這個類的家族,因為編譯器會自動找出合適的對象來執行操作。這種現象又稱為多態性。而實現多態性的手段又叫稱動態綁定(dynamic binding)。

簡單的說,建立一個父類對象的引用,它所指對象可以是這個父類的對象,也可以是它的子類的對象。java中當子類擁有和父類同樣的函數,當通過這個父類對象的引用調用這個函數的時候,調用到的是子類中的函數。

閱讀全文

與編譯時多態性可通過什麼實現相關的資料

熱點內容
ug命令視頻大全 瀏覽:610
箱子裝貨物最小容量編程 瀏覽:99
cad2014教程pdf 瀏覽:200
怎麼遍歷伺服器同一類型的文件 瀏覽:437
惠普戰66畫圖編程 瀏覽:806
java面向對象作業 瀏覽:570
cad插件製作加密狗 瀏覽:924
cmd命令對話框 瀏覽:291
安卓應用怎麼常駐 瀏覽:677
安卓手機怎麼群發小費才不會被鎖 瀏覽:742
相機文件夾設置 瀏覽:856
centos7php怎麼用 瀏覽:120
查看linux操作系統版本的命令 瀏覽:384
收支預演算法怎麼做 瀏覽:876
模板如何上傳到伺服器 瀏覽:373
如何同步安卓信息到新ipad 瀏覽:365
騰訊雲輕量伺服器流量警告 瀏覽:504
u盤備份linux 瀏覽:121
高壓縮比活塞 瀏覽:93
壓縮彈簧標准件 瀏覽:27