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

错误|对象

 

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

时间: 2024-08-24 04:47:55

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

做一个饲养员给动物喂食物的例子体现JAVA中的面向对象思想,接口(抽象类)的用处

做一个饲养员给动物喂食物的例子体现JAVA中的面向对象思想,接口(抽象类)的用处 interface Animal{             //动物的接口    public void eat(Food food); //接口中只有抽象的方法和静态常量!这里void前面省略了abstract.同样,变量可以省略static final} class Cat implements Animal //一种动物类:猫  {      public void eat(Food food) //这里是对

android 做一个每个item都类似viewpager可以多张图片滑动的列表

问题描述 android 做一个每个item都类似viewpager可以多张图片滑动的列表 android 做一个每个item都类似viewpager可以多张图片滑动的列表.业务需要,还没有看到有可以借鉴的例子,谁能提供帮助吗? 解决方案 你用viewpager封装一个就行了,你只需要把图片传进去,内部自己就创建滑动相关的元素 解决方案二: 不用fragment,而是直接传图片进去? 解决方案三: 不用fragment,而是直接传图片进去? 解决方案四: 不用fragment,而是直接传图片进去

mfc初学者,想做一个基于对话框的类似搜索引擎的程序,有没有功能相近源代码借鉴一下

问题描述 mfc初学者,想做一个基于对话框的类似搜索引擎的程序,有没有功能相近源代码借鉴一下 关于注册时的用户名密码怎么存啊,数据库怎么用啊,搜索的文件放哪啊等等问题,不胜感激 解决方案 最简单的是嵌入一个webbrowser控件,链接到网站上. 解决方案二: 建议楼主先参考书籍去MFC 体验一下控件的使用和相关响应函数的编写吧,先动手操作再想思路 解决方案三: 先学好基础再想做实际程序,数据库怎么用这些不是一两句话能说清楚的

面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了;面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为(转)

谈谈你对面向对象的理解 面向对象编程,即OOP,是一种编程范式,满足面向对象编程的语言,一般会提供类.封装.继承等语法和概念来辅助我们进行面向对象编程. 面向对象是基于万物皆对象这个哲学观点. 所谓的面向对象就是将我们的程序模块化,对象化,把具体事物的特性属性和通过这些属性来实现一些动作的具体方法放到一个类里面 面向对象的三大特征 继承,封装,多态 一 继承 继承概念:一个类继承另一个类,则称继承的类为子类,被继承的类为父类. 目的:实现代码的复用. 理解:子类与父类的关系并不是日常生活中的父子

WPF动态生成TreeView 之后点击树中的一个节点,怎么打开一个新界面,类似VS一样

问题描述 WPF动态生成TreeView之后点击树中的一个节点,怎么打开一个新界面,类似VS一样<!--treeview的代码--><TreeViewx:Name="tvMenu"ItemsSource="{BindingSource={x:Staticlocal:TreeViewData.Data},Path=RootNodes}"HorizontalContentAlignment="Stretch"Background=&

存储-请问可以对一个记事本文件进行类似数据库操作吗?

问题描述 请问可以对一个记事本文件进行类似数据库操作吗? 类似简单的查询语句之类 .我只找见了对EXCEL操作的例子,如何对记事本文件进行数据库操作, 就是对存储在记事本文件中的内容进行select操作,怎么定义数据源,怎么定义对象? 解决方案 可以,将文件保存为csv格式(逗号分隔的数据),可以用oledb引擎像数据库那样读取. 解决方案二: 这个直接用io就可以了吧.毕竟记事本和excel和数据库来说,相当于白纸了

请教如果在word2003中添加一个工具栏按钮(类似与金山词霸那样)

问题描述 请教如果在word2003中添加一个工具栏按钮(类似与金山词霸那样) 解决方案 解决方案二:想用C#代码实现,有难度,顶下吧,看高手怎么说的..

JavaWeb实现同一帐号同一时间只能一个地点登陆(类似QQ登录的功能)_java

JavaWeb实现同一帐号同一时间只能一个地点登陆(类似QQ登录的功能)的实现思路如下所示: 一.该功能有什么作用 大家想想吧.反正总会有这样的需求的.这年头什么需求不会有..呵呵.有时候也不一定是需求,很有可能为了安全也会这么做.例如考试系统,在线聊天系统,很有必要做成这样的吧. 二.实现过程 a.问题分析 在系统中,我们一般都是把登录信息绑定到session中,看来从这入手是可能找到解决办法.说白了,也就是当用户登录时,判断一下这个用户有没有登录,如果登录了,就把以前的那个session清除

Javascript基础与面向对象基础~第五讲 Javascript中的方法,类中的方法

上一文章主要说的是JS中的类,有很多朋友回复了我的文章,在此很感谢大家,也对一些朋友提出的问题进行了回复,"类"这东西,只是一种思想,我们不应该把重点放在"某种语言是否提供类,或者是否实现了类",这是不重要的,重要的是面向对象中的类的思想! 今天主要说的是方法,JS中的方法也叫做函数function,它将一些有关系的代码组织在一起,形成一个整体,这类似于面向对象中的封装,你不需要了解方法的实现细节,你只要去调用它,了解方法的签名即可. 最简单的函数(方法): <