首页 > 开发 > Java > 正文

一个在C#以及类似的面向对象系統(Java中估计也是如此)中常见的错误

2024-07-21 02:27:13
字体:
来源:转载
供稿:网友

 

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中估计也是如此)中常见的错误  回复   
先收藏做个标记

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表