我想把继承讲好一点,希望大家能给点建议。谢谢!继承

解决方案 »

  1.   

    “儿子继承父亲的优点”跟OOAD的继承是完全不同的。所谓继承,是指概念意义上的继承,也就是一种“is-a”关系。如果是B继承于A,那么一个B它“就是”一个A。例如张柏芝就是一个女人、也是一个演员、对于某会所来说也是一个VIP。谁敢说它自己“就是自己的爸爸”?不敢吧!因此把父子关系说成是OOAD的继承,是不懂OO设计概念的。你可用这个作为反例,来教会你的学生分辨继承和非继承。
      

  2.   

    例如我们说“我今天上街买了一条外边穿的大裤衩”,那么听到这个话的“正常人”就知道我今天“买了服装”。因为大裤衩“is-a”服装。那么假设这是软件系统,就会把大裤衩“多态地”带入服装处理的中,例如精品店会使用服装销售模块来录入销售信息,而不是使用大裤衩销售模块(可能精品店也没有这个模块)。事实上,简单的概念,学生反而不能理解其深刻的道理,需要很多年实践来强化这些最简单的概念。但是你仍然要尽量给他们讲明白这个道理。注意不要用什么“儿子继承父亲的财产”之类错误概念来误导他们。
      

  3.   

    在缺乏结构化编程概念的人看来,所谓“大裤衩”就是一个id编号,加上颜色、尺寸、版型等等属性,它以为弄个数据库ER图,弄几条关系数据库增删改查语句,这就是设计。它们只看到最低级的属性,例如只能看到string、int、bool、数组等基本类型,而看不到千姿百态的“用户自定义类型”。因此这些人缺少基本的概念“封装”的能力。有些人只知道概念,而无法想象出无数“对象”独立地“存在、运行”的状态。例如两个长得一摸一样、味道完全一样的苹果让然是两个独立的苹果,但是他就总觉得这两个苹果有什么神秘的诡异概念复制出来的。因此这些人缺乏“对象都是独立的,可唯一标识的”的认知能力。有些人学了一定时间的编程,会自定义一些class或者struct了,但是他对继承一直耿耿于怀,他总是心里想不通“子类既可以继承父类的方法,也可以重写(消解)父类的方法”,这样的人难以理解继承。(不过这样的人也许在结构化方面还不错)有些人滥用继承,把不是继承的东西说成是继承。仅仅为了省得写几行代码,或者别的什么道听途说的原因就去滥用继承。他们产生了各种各样诡异的子类,很快就给产品制造了概念危机。滥用继承的人比丝毫不接受继承的人,不会更好。
      

  4.   

    首先问你的学生一个问题。User a;这是什么意思。你的学生保管都会说,这是定义了一个叫做a的User类型的对象。当然,这在谭浩强的年代是没有什么问题的。但是在一种支持继承的语言中,这么说就片面了。User a;表示a可以是一个User类型,或者User的派生类型。如果能理解了这一点,那就好办了。我再问一个问题,User的派生类型有哪些?我也不知道。当然你可以在代码中找一下,但是事实上,你在我写好了这一行之后,可以新定义几个派生自User的类型。因此User的派生类型可以有无数多个。好了。使用User类型的开发者可以忽视定义User派生类型的程序员的存在而存在了。比如说,他写这么一个逻辑,判断一个用户是否被授权做一个操作,如果用户有这个权限,就继续下面的逻辑,他可以这么写:
    class User
    {
        ...
        public virtual bool Authentication(string ActionName) { return false; }
    }void DoSomething(User currentUser)
    {
        if (User.Authentication("something")) //判断是否有权限
        {
            ...
        }
        else
        {
            throw new Exception("没有权限");
        }
    }他定义好User类,并且写好通用的逻辑而定义User派生类的程序员,则可以独立地为User的派生类添加新的代码,具体设计某个特定的用户拥有什么权限,设置他可以从用户的个性设置中加载和判断。class SuperUser
    {
        //超级用户,无论什么操作,都允许他做。
        public override bool Authentication(string ActionName) { return true; }    
    }请注意,编写具体做什么操作的程序员和定义什么用户能做什么操作的程序员是两个人。他们通过定义和继承对象发生联系,但是很明显,前者无需后者就能展开工作。后者呢,他不需要修改前者的代码就可以扩展新的用户类型。想象下没有继承我们怎么写同样的代码:
    void DoSomething(object currentUser)
    {
        bool checkresult = false;
        if (currentUser Is AdminUser)
        {
            checkresult = (currentUser As AdminUser).Authentication("something");
        }
        if (currentUser Is SuperUser)
        {
            checkresult = (currentUser As SuperUser).Authentication("something");
        }
        if (currentUser Is GuestUser)
        {
            checkresult = (currentUser As SuperUser).Authentication("something");
        }
        ...
        if (checkresult) //判断是否有权限
        {
            ...
        }
        else
        {
            throw new Exception("没有权限");
        }
    }[/code]
    我们需要人工去完成类型的判断,并且调用各自的方法——不同的Authentication方法没有联系。那么很显然,每次那个负责编写用户权限的人定义了新的用户类型,就要去找那个编写具体操作的人索要一次代码,并且修改它。你可以让你的学生几个人编为一组,去体验下,到底是各司其职地协同开发好,还是一个人必须依赖另一个人修改他的代码才能完成自己的工作的方式好。
      

  5.   

    知道继承的概念,对于OOAD知识来说,相当于一个基本概念,从篇幅上看很少。打开一本OOAD(或者具体一些——UML方面的)教科书,假设它有600页,那么继承这个概念占不到一页纸。
      

  6.   

    真心受教了,感谢各位大神!
    曾经自学过一段时间C语言,
    现在学校学习java和C#,当初转变OOP思想时候看了好多资料才理解什么是面向对象,下面是我的理解两页纸中间夹张拓印纸,
    在第一页纸上画个圆,(父类)
    (继承)拓印纸下面一页也会有一个圆,(子类拥有父类所有属性和方法),
    但如果在拓印纸的下一页的圆中画条线,上一页并不能识别,但是上一页可以识别他本身(也就是那个圆)?不知道这样说对不对