爲什麼重載稱爲編譯時多態性和在C#中重寫運行時多態性?編譯時間多態性與運行時多態性
回答
重寫函數是具有相同簽名的函數,但在不同派生類中實現。在編譯時,基類類型通常用於引用對象,但在運行時該對象可以是派生類型的,所以當調用重寫的方法時,被調用的實現取決於哪種類型的對象在編譯時進行調用(基類與派生類型),這是未知的。
重載(不是真正的多態)只是具有相同名稱但簽名不同的多個函數(認爲具有不同數量參數的對象的多個構造函數)。在編譯時調用哪個方法是已知的,因爲此時指定了參數。
因爲在編譯時已知調用了哪些重載函數,但對於重載函數並不總是這種情況。
嗯,超載的決定(其方法簽名被使用,基於所述參數)由編譯器製成的,而覆蓋用於決定(該方法實現方式中,基於目標的類型)是由CLR在執行時制定的。
雖然我通常不會調用重載「多態性」。根據我的經驗,這個詞通常是指的是重寫。我想超載確實允許您將一種類型的對象視爲另一種類型的對象,儘管重載本身並不需要參與 - 它只是普通的類型轉換。
下面是示出在編譯時執行的過載的選擇的一個示例:
using System;
class Test
{
static void Foo(object a)
{
Console.WriteLine("Object overload called");
}
static void Foo(string a)
{
Console.WriteLine("String overload called");
}
static void Main()
{
object x = "hello";
Foo(x);
}
}
這裏Foo(object)
過載被稱爲因爲x
是在編譯時object
型的 - 這是隻有在執行時,它的已知的參考到一個字符串。
相比之下,與這個例子:
using System;
class Base
{
public virtual void Foo()
{
Console.WriteLine("Base.Foo called");
}
}
class Derived : Base
{
public override void Foo()
{
Console.WriteLine("Derived.Foo called");
}
}
class Test
{
static void Main()
{
Base x = new Derived();
x.Foo();
}
}
這裏編譯時型x
爲Base
,但它仍然是派生類的重載方法,它是所謂的,因爲執行時間型x
指的對象是Derived
。
這比,其實稍微複雜一些,由於方法隱藏等等 - 但在簡單的情況下,你可以把它看成只是挑選簽名。
靜態多態性的經典示例基於template metaprogramming或Duck Typing,但不是方法重載。
靜態多態性意味着desicion是通過編譯器(靜態)創建的,而動態多態性意味着只在運行時(動態)進行求解。
編譯時多態性
假設可以說你有2種方法如下:由於該方法共享相同的名稱,但具有不同的參數;它被稱爲「重載」方法。 吃(串食物); 吃(串食物,串SpoonOrFork);
,你在你的晚餐類使用現在這個樣子
public class Man
{
public bool Eat (string food)
{
//implementation
}
public bool Eat (string food, string SpoonOrFork)
{
//implementation
}
}
public class dinner
{
public bool Start()
{
string food = "course1";
Man.Eat (food);
}
}
當你編譯該程序的編譯器正好知道吃的方法在編譯時間本身調用(因爲在參數的差異)的哪個版本。
這就是爲什麼它被稱爲編譯時多態性的原因。
運行時多態性
public class chimp
{
public virtual void walk()
{
Console.WriteLine("I am walking using 4 legs");
}
}
public class neanderthals : chimp
{
public override void walk()
{
Console.WriteLine("I am walking using 2 legs");
}
}
class Program
{
static void Main(string[] args)
{
chimp x = new neanderthals();
x.walk();
Console.ReadLine(); // this will give an output of "I am walking using 2 legs"
}
}
在上面的代碼X是型黑猩猩的。即使編譯器認爲它將在chimp中調用walk方法;但那不是實際發生的事。由於它依賴於CLR(運行時間),因此這種多態稱爲「運行時」多態。
多態性
通過繼承,一類可以用作多於一種類型;它可以用作自己的類型,任何基類型,或者任何接口類型(如果它實現接口)。這被稱爲多態性。
多態性意味着具有多種形式。重載和重寫用於實現多態。多態性分爲編譯時多態性或早期綁定或靜態綁定和運行時多態或後期綁定或動態綁定。
覆蓋 - 具有相同參數和相同返回類型的相同方法名稱與類及其子類關聯。在C#中覆蓋使用「覆蓋」關鍵字。重寫一個方法意味着用一種新的數據處理方式替換它。
重載 - 具有不同參數的相同方法名稱可能是也可能不是相同的返回類型寫入同一類本身。
編譯時間多態性或早期綁定
在其中它具有多晶型形式的編譯器識別到在編譯時執行它自被稱爲編譯時多態性或早期綁定多態性。
早期綁定的優點是執行速度會很快。因爲在編譯過程中編譯器知道該方法的每一件事情,所以它自身和缺點是缺乏靈活性。
早期綁定的例子是重載方法,重載操作符和通過派生對象直接調用的重載方法。
運行時多態性或後期綁定
多態性,其中在運行時執行該多晶型物,但不能在編譯時間編譯器識別被稱爲運行時多態性或後期綁定。
後期綁定的優點是靈活性和缺點是執行會很慢,因爲編譯器必須獲取有關在運行時執行的方法的信息。
後期綁定的示例是使用基類對象調用的重寫方法。
class A
{
public virtual void Leg(string Name)
{
}
}
class B:A
{
public override void Leg(string Name)
{
}
}
實施例用於在裝載
class A
{
void a()
{
}
void a(string Name)
{
}
}
換言之,「單個對象的許多形式被稱爲多態性」。例如:
例如:
一個團隊負責人表現爲SubSteate。 一名隊長對他/她的前輩表現出色。 團隊負責人對其他團隊負責人表現出色。
這裏團隊領導是一個客體,但態度在不同的情況下是不同的。方法覆蓋與方法之間
差分隱藏
方法覆蓋允許一個子類,以提供一個具體的實施已經由基類提供的方法。子類中的實現覆蓋(替換)基類中的實現。 關於覆蓋重要的是需要重寫的方法與基類中的方法相關。 當在引用上調用虛擬方法時,引用所引用的對象的實際類型將用於確定應使用哪種方法實現。在派生類(子類)中重寫基類的方法時,將使用派生類中定義的版本。即使調用應用程序不知道對象是派生類的實例,這也是如此。
方法隱藏在基類和派生類中的方法之間沒有關係。派生類中的方法將該方法隱藏在基類中。
它被稱爲運行時多態性,因爲行爲是在運行時決定的,而不是編譯時間。
當您調用像objectVariable.Method()這樣的方法時,您的機器將調用哪種方法將取決於objectVariable中存在哪個類實例,並且在將類的實例分配給它之後決定。這將在運行時發生,而不是在編譯時發生。因此名稱爲「運行時多態」。
你可以讀到更多在:What is the difference between compile time and run-time polymorphism
編譯時多態性
編譯時多態也被稱爲方法重載。 方法重載意味着有兩個或多個方法具有相同的名稱但簽名不同。
運行時間多態性
運行時間多態性也被稱爲方法覆蓋。 方法覆蓋是指具有兩種以上的方法具有相同的名稱和相同的簽名,但具有不同的實現
多態性
多態性是指許多形式(能夠採取多個形式)。在多態中,poly表示「多重」,morph表示「形式」,所以多態意味着多種形式。
在多態性中,我們將在不同的類中聲明具有相同名稱和不同參數的方法在相同類或方法中具有相同名稱和相同參數。多態可以提供用相同名稱實現的不同方法的實現。
在多態性我們有2種不同類型的那些
- Compile Time Polymorphism (Called as Early Binding or Overloading or static binding)
- Run Time Polymorphism (Called as Late Binding or Overriding or dynamic binding)
編譯時多態性
編譯時多態是指,我們將宣佈與名稱相同,但因爲這個不同簽名的方法,我們將執行不同的任務相同的方法名稱。這種編譯時多態也被稱爲早期綁定或方法重載。
方法重載或編譯時多態是指具有不同的簽名同樣的方法名稱(不同參數)
有關詳情,請在C#中這個環節多態性
運行時多態性
運行時多態性也被稱爲作爲後期綁定或方法重寫或動態多態。運行時多態或方法覆蓋意味着具有相同簽名的相同方法名稱。
在此運行時多態性或方法重寫中,我們可以通過在派生類中創建類似函數來重寫基類中的方法,這可以通過使用繼承原理和使用「虛擬&重寫」關鍵字來實現。
- 1. 什麼是運行時間和編譯時間多態性?
- 2. 運行時多態性
- 3. Java編譯時非多態性
- 4. Fortran 2003中的運行時多態性
- 5. C++/Boost模板運行時多態性
- 6. 多態性:運行時間鑄造指針
- 7. 多態性與AutoMapper
- 8. 數據成員的編譯時多態性
- 9. JAXB編組和多態性
- 10. 通過多態性在運行時定義變量的類
- 11. 運行時多態性究竟意味着什麼?
- 12. 需要幫助解決運行時多態性使用模板
- 13. 實現運行時多態性和繼承
- 14. C#泛型與多態性
- 15. 多態性與客體
- 16. 多態性與解釋
- 17. 逆多態性與外生
- 18. 與多態性在Haskell
- 19. Rails:多態性與否?
- 20. 與多態性的ArrayList
- 21. C++多態性與切片
- 22. 擴展類,組成與多態性時的性能
- 23. 約多態性
- 24. C++多態性
- 25. 多態性質
- 26. F#多態性
- 27. 多態性Enums
- 28. Cassandra多態性
- 29. 多態性Golang
- 30. 爪哇 - 多態性與集合屬性