因为子类继承了父类的特性,所以子类是在父类功能上的扩展,那么将子类如b实例赋值给父类a变量,那么这个父类a变量也可以正常的调用父类定义下的成员的。反过来赋值的活,b实例想要调用子类自己扩展的方法时,就无法调用了,因为赋值的父类实例a没有定义这个功能。  
接口是不一样的,接口是定义一套协议,接口不能被实例化,实现接口的类必须全部实现接口定义的方法,那么我们在接口编程的时候,将类实例赋值给接口变量,我们接口变量就可以正常调用类实现的接口的方法了。

解决方案 »

  1.   


    变量引用实例,那变量类型要和实例的类型相同吧
    例 String a="1"
         String b ="2"
         a=b可以,是因为a,b所属的类型是一样的,都是String类型
    那父类和子类是相同的类型吗?
      

  2.   

    我的困惑类似http://bbs.csdn.net/topics/360054603这里提到的
      

  3.   

    也挺难一两句说明白,因为编译器编译了代码,所以编译器就知道怎么去调用,好像是废话
    人是动物,但是不能说动物是人,楼主已经理解这种说法,为了满足这种特性,设计语言的人才去整出来的方案
    设计语言的人弄出来的这种实现方式应该不是唯一的
    C# 是怎么设计的没研究过,不过可以给你简单说一下 C++,我想 C# 也八九不离十C 的一个结构 A 定义为 { int a;} 结构 B 定义为 {int a; int b;}
    B 比 A 多了一个 b,那么如果搞出一个继承的说法:
    说 B 继承了 A 的时候 B 只要定义自己的成员即可 B:A {int b;} int a 已经隐式的从 A 那里获得用 C 的方式 B* p 可以当作 A* 来用吗?肯定可以,因为 A* 的第一个成员和 B* 的第一个成员都是 a
    A* 可以当 B* 用吗?某些情况不行,访问成员 b 的时候可能属于越界访问
    这样你应该能理解父类和子类怎么在内存中排列,为什么子类能当父类用实际情况类比结构复杂的多,不是只有一些变量,还有函数等等,好在还有函数指针这玩意,只要多跳几次
    总能找到真正要调用的函数,所以在对象内存里先放一个记录函数指针的表的地址,
    先找到那个表,表里的第一个偏移量的函数指针是f1,第二个是f2……
    f1 到底指向了哪里?编译器知道,它会给填进去的, A* 和 B* 谁能当谁用?应该不难理解内存布局和编译器是配合着玩的,所以当编译一段代码的时候偏移是4还是8,就是设计的人说了算,
    不怕麻烦自己设计一套方案也行好在 C# 不允许继承多个基类,它还是抛弃了 C++ 一些不知道好还是不好的玩意,楼主可以自己想话说回来,这个问题,我认为答案还是“人是动物,动物不一定是人“
    这种逻辑概念导致了面向对象语言的这种实现,而不是现在的这种实现导致了这个结果