我刚学C#,以下Person是一个抽象类,Student是Person的继承类
Person person;
Student student=new Student();
person=student;
请问为什么可以将person=student这样用啊?student不是一个对象吗?怎么将一个对象赋值给一个变量了,而且student和person的类型也不一样啊;
请解释详细点,谢谢啊!

解决方案 »

  1.   

    因为Student继承至person的,因此就确定了他们的一个特殊关系。所有的子类的实例都是可以当作父类来使用的。就好比,父类是一个小圆筐子,子类是一个大圆框子(功能更多)。大圆框子可以只装小圆框子的那些东西,而小圆框子无法装下大圆框子的东西,即父类的实例不能转换成子类的实例。另外如果转换成方框子(即其他类的实例)显然也是不行的。
      

  2.   

    Person person; 
    Student student=new Student(); 
    person=student; student不是一个对象吗?student是Student类型的一个实例
    person是Person类型的
    向上转型为安全的,
    //此student(实例)而非Student(类)
      

  3.   

    Person person 这条语句是创建一个空的person对象,(理论上来说,在堆里没有指向的地址)而不是变量!!
    Student student=new Student(); 这条语句是创建了student的对象,(理论上来说,在堆里有指向的地址)
    person=student; 这条语句,因为student是继承类,所以赋给person完全合法!!
      

  4.   

    中国人 person;
    台湾人 张三 = new 台湾人();
    person = 张三;           //因为张三是台湾人,台湾人 "is a" 中国人 person = new 香港人();   //当然也可以这就是多态了变量与对象是两个不同范畴的概念,不冲突
      

  5.   

    person,student都是对象,他们都是引用类型,也就是当创建一个实例的时候,他们可以理解为只是一个数据结构,
    Person person; 
    Student student=new Student(); 
    person=student; 这里的person是个引用类型,也就是persona也指向了student的地址的引用,但student本身继承了person所有的方法和属性,并且student自己扩充了自己的方法喝属性,就像二楼说的一样,大圆与小圆的例子,大圆是student,小圆是person,大圆里面包括小圆的方法和属性,现在person指向了student的实例,Person person对象指向了student继承了Person类的所有方法与属性,就是小圆指向了大圆中的小圆所以可以隐形转化。如果反一下student=person,student指向了父类,那么student就要写成student=(student)person,student的方法与属性大于父类的方法与属性,就形如long int转化成int一样,要强制转化。int转化成long int就隐形转化
      

  6.   

    我想知道现在person属于什么啊?
      

  7.   

    Person 是对象名,student 是Person 的一种。
    person=student 是为了把student看做一个Person来处理,而忽略掉Student特有的东西。具体点儿说:人都要吃饭(拥有吃饭的方法),学生需要学习(有学习的方法),这样,人本身是不一定都需要学习的。这时,我们实例化出一个学生,想要让这个学生吃饭,我们不需要告诉他:“你是一个学生,你需要吃饭”,而是直接告诉他:“你是一个人,你需要吃饭”。所以,在这个例子中,我们的过程是这样的:
    Person person; //// 有一个人
    Student student=new Student(); //// 有一个学生(等号右边,相当于你拉过来一个学生,让大家实际看到了这个学生)
    person=student; //// 最后这步就有意思了。我们接着上面的情景就是,我们指着这个学生说:这就是我前面说的那个人了。
      

  8.   

    Person person; //现在person是一个对象也就是一个实例,但目前它只是一个空的对象,它的值为null,因为还没给它赋值;
    Student student=new Student(); //student是一个对象也是一个具体的实例,它通过new构造函数子后不是null了,它有了具体的东西;
    person=student; //之后person不为null了,因为它也指向了student的地址的引用。person只能使用它定义的属性和方法;student不但可以使用person定义的属性和方法,还可以使用它自己定义的属性和方法
      

  9.   

    首先你要明白,定义了一个类的变量的时候, 比如你这定义的Person  person ; 这个person变量会对应一个的虚指针表,其中的指针分别指向这个类各个属性,字段方法事件之类所对应的地址.比如
    Class Person
    { string name ;
      int age ;
      public void sayHello()
      {//hanshu ti 
      }
    }而当你定义一个新的类来继承这个类的时候,比如
    Class Student :Person
    {
     string school ;
    // 等等
    }
    这是你再声明一个Student 类的时候 ,变量对应的会在其继承类的虚指针表中添加指向新加的诸如字段属性方法事件之流的指针.
    当你把 Student 类的赋给Person 类的时候,会自动取Student类虚指针表中的继承自Person类的指针序列来赋值Person类对应对象的虚指针表.
    这样操作Person实际上操作的是其子类Student的方法.因为其指针指向Student对象所对应的.
    当然关于Student里面自己新加的 ,Person对其是不可见的,因为他没有对应的指针.所以虽然操作的是Student对象的方法,不可以操作新添加的东西.
    说的有点简单,不知道这么说你能明白不. 要不你就自己查下继承的本质.多看点虚指针表之类的.
      

  10.   

    上面倒数第5句该成下面这样也许能好理解点.
    这是你再声明一个Student 类的时候 ,变量对应的会在其继承类的虚指针表中添加指向新加的诸如字段属性方法事件之流的指针.来形成新的虚指针表(其结构也就是Student类所对应的虚指针表的结构.)每个类会对应一个类型的虚指针表. ,可以认为子类的表结构是在父类结构基础上的添加.