文章目錄
- 1、公有方法實現介面方法
- 2、私人方法不能實現介面方法
前不久看到一文章:
http://zhenyulu.cnblogs.com/archive/2006/04/18/377705.html
C#介面
(未完整摘錄)
本文將通過以下四個案例來分析C#中的介面究竟是如何工作的。
1、公有方法實現介面方法
儘管C#在定義介面時不用指明介面方法的存取控制方式,但預設介面方法均為public型(這可以從反編譯的IL代碼中看到)。下面是使用Reflector查看的介面IL代碼
.class private interface abstract auto ansi IControl{ .method public hidebysig newslot abstract virtual instance void Paint() cil managed { }}
實現介面的類需要實現所有介面方法。通常情況下,介面的實現方法也為public型。如下案例:
using System ;interface IControl { void Paint();}public class EditBox: IControl { public void Paint() { Console.WriteLine("Pain method is called!"); }}class Test { static void Main() { EditBox editbox = new EditBox(); editbox.Paint(); ((IControl)editbox).Paint(); }}
程式的執行結果為:
Pain method is called!Pain method is called!
介面就好像是關係型資料庫中的一對多表,一個介面對應多個介面方法,每個介面方法又對應虛擬方法表(VMT)中的某個公有或私人方法。上面代碼在記憶體中的鏡像可由描述:
我們可以看到直接對Paint方法的調用以及通過介面對Paint方法的調用。可見通過介面對方法進行調用需要多出一道轉換工作,因此執行效率不如直接調用。
2、私人方法不能實現介面方法
如果想將介面方法直接實現為私人方法是辦不到的。下面的EditBox的代碼中Paint方法沒有特殊說明,預設為private,導致代碼無法執行:
using System ;interface IControl { void Paint();}public class EditBox: IControl { void Paint() { Console.WriteLine("Pain method is called!"); } public void ShowPaint() { this.Paint(); ((IControl)this).Paint(); }}class Test { static void Main() { EditBox editbox = new EditBox(); editbox.ShowPaint(); }}
程式在編譯時間將顯示如下編譯錯誤:““EditBox”不會實現介面成員“IControl.Paint()”。“EditBox.Paint()”或者是靜態、非公用的,或者有錯誤的傳回型別。”
為什麼會這樣呢?
這是由於介面規範中的方法預設的存取權限是public,而類中的預設存取權限是default,也就是說private,因此導致許可權範圍收縮,兩者許可權並不相同,所以必須將類的許可權調整為public才可以使上面的代碼得以執行。
然後式了下 cpp的vtable規則..
#include <iostream>
using namespace std;
class IControl
{
public:
virtual void Paint() =0;
};
class EditBox: public IControl
{
private:
void Paint()
{
cout<<"sads"<<endl;
}
public:
void ShowPaint()
{
this->Paint();
((IControl*)this)->Paint();
}
};
int main(int argc, char* argv[])
{
EditBox *editbox = new EditBox();
editbox->ShowPaint();
return 0;
}
在 cpp下是恰當的..符合我得預期..
cpp vatble的 重寫沒有存取權限的控制.