using system;
namespace demo
{
class classa
{
protected string a = "test";
public void display()
{
console.writeline(a);
}
}
class classb:classa
{
protected string a = "another test";
}
/**//// <summary>
/// summary description for class1.
/// </summary>
class class1
{
/**//// <summary>
/// the main entry point for the application.
/// </summary>
[stathread]
static void main(string[] args)
{
//
// todo: add code to start application here
//
classb instance = new classb();
instance.display();
((classa)instance).display();
console.readline();
}
}
}
此時控制臺輸出的內容兩次都是test
但是如果做如下修改:
using system;
namespace demo
{
class classa
{
private string _a = "test";
protected virtual string a
{
get
{
return _a;
}
set
{
_a = value;
}
}
public void display()
{
console.writeline(a);
}
}
class classb:classa
{
private string _deriveda = "another string";
protected override string a
{
get
{
return _deriveda;
}
set
{
_deriveda = value;
}
}
}
/**//// <summary>
/// summary description for class1.
/// </summary>
class class1
{
/**//// <summary>
/// the main entry point for the application.
/// </summary>
[stathread]
static void main(string[] args)
{
//
// todo: add code to start application here
//
classb instance = new classb();
instance.display();
((classa)instance).display();
console.readline();
}
}
}
那么控制臺輸出的都是:another test
如果我們做如下修改,
using system;
namespace demo
{
class classa
{
private string _a = "test";
protected virtual string a
{
get
{
return _a;
}
set
{
_a = value;
}
}
public virtual void display()
{
console.writeline(a);
}
}
class classb:classa
{
private string _deriveda = "another string";
protected new string a
{
get
{
return _deriveda;
}
set
{
_deriveda = value;
}
}
public new void display()
{
console.writeline(a);
}
}
/**//// <summary>
/// summary description for class1.
/// </summary>
class class1
{
/**//// <summary>
/// the main entry point for the application.
/// </summary>
[stathread]
static void main(string[] args)
{
//
// todo: add code to start application here
//
classb instance = new classb();
instance.display();
((classa)instance).display();
console.readline();
}
}
}
那么程序的輸出結果是:
another test
test
很有趣的一件事情,因為我在項目的源代碼中發現了一個因為誤用而引起的錯誤
如下:
using system;
namespace demo
{
class classa
{
protected string a = null;
public void display()
{
console.writeline(a);
}
}
class classb:classa
{
protected string a = "another test";
}
/**//**//**//// <summary>
/// summary description for class1.
/// </summary>
class class1
{
/**//**//**//// <summary>
/// the main entry point for the application.
/// </summary>
[stathread]
static void main(string[] args)
{
//
// todo: add code to start application here
//
classb instance = new classb();
instance.display();
console.readline();
}
}
}于是在程序的運行中產生nullreferenceexception
posted on 2005-06-15 16:32 dark 閱讀(1468) 評論(9) 編輯 收藏 收藏至365key
評論
# re: 一個在c#以及類似的面向對象系統(java中估計也是如此)中常見的錯誤 回復
在派生類如果要寫一個函數替代父類的同名函數必須用new操作符,否則實際的執行效果是不確定的,
比如你這種情況如果想要classb的實例在不override的情況下執行自己的display要這樣定義display:
public new void display()
{
...
}
2005-06-15 16:58 | teddy's knowledge base
# re: 一個在c#以及類似的面向對象系統(java中估計也是如此)中常見的錯誤 回復
你有這種問題,只能說明oo不到家,還要好好學習一下阿!
2005-06-15 17:21 | hon young
# re: 一個在c#以及類似的面向對象系統(java中估計也是如此)中常見的錯誤 回復
實際執行的效果都是確定的,不管是在.net還是在java系統中,在java中是如何確定的我就不是很清楚了,問題在于這些面向對象的規則即決定具體行為的規則最好能夠以iso的方式規范化就好了,不管是在c++,.net,java還是python中,我們都能夠獲得相同的語義
2005-06-15 17:26 | mixed it up
# re: 一個在c#以及類似的面向對象系統(java中估計也是如此)中常見的錯誤 回復
是理解oo的錯誤。
class classa
{
protected string a = "test";
public void display()
{
console.writeline(a);
}
}
class classb:classa
{
protected string a = "another test";
}
等于classa有一個string a,classb 也有一個string a,二者不同的,是2個變量。
2005-06-15 17:34 | pierce
# re: 一個在c#以及類似的面向對象系統(java中估計也是如此)中常見的錯誤 回復
不是...很明白第三種情況....強制轉換類型之后變量也用了基類的變量.....難道是我一直理解錯了...
2005-06-15 18:44 | 補丁
# re: 一個在c#以及類似的面向對象系統(java中估計也是如此)中常見的錯誤 回復
這樣的輸出才是符合oo原理的
2005-06-15 20:27 | 男
# re: 一個在c#以及類似的面向對象系統(java中估計也是如此)中常見的錯誤 回復
這叫錯誤?好好學學oo再做事吧,暈。
2005-06-16 09:36 | yun
# re: 一個在c#以及類似的面向對象系統(java中估計也是如此)中常見的錯誤 回復
to all:
我可以建議大家去看看侯杰的《c++對象模型》,就能很好的理解為什么是這樣了。比如把一個子類對象強制轉換為基類對象,其實編譯器處理就是把該對象作為基類對象來處理(即對象的slip)。當然調用的方法也是基類的方法,和子類無關。
to hon young :其實你也說錯了, 這不能說是oo的范疇(oo僅僅是一種思想),應該是編譯器的對象模型范疇(是一種存技術)
總之,大家要知道,等編譯完成后,所有的內存分布及調用(地址偏移量)都已經確定了....
請瀏覽《希望這篇文章對理解c#的對象模型有所幫助 》:http://www.cnblogs.com/caomao/archive/2005/06/16/175459.html
2005-06-16 10:08 | zendyhu
# re: 一個在c#以及類似的面向對象系統(java中估計也是如此)中常見的錯誤 回復
先收藏做個標記
新聞熱點
疑難解答
圖片精選