一個在C#以及類似的物件導向系統(Java中估計也是如此)中常見的錯誤

來源:互聯網
上載者:User
錯誤|對象

 

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中估計也是如此)中常見的錯誤  回複   
先收藏做個標記



相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.