C#继承中的对象范围

时间:2014-04-04 13:05:50

标签: c# oop

我是开发和初学者的新手。我在C#学习OOP。我想知道以下概念: -

  1. 为什么派生类对象被分配给基类对象,但它的反面却不是?
  2. 此场景中派生类和基类对象之间的内存分配流是什么?
  3. //I have done this practically
    
    // This is base class
    
    Student student = new Student();
    
    //This is derived class
    SchoolStudent schoolStudent = new SchoolStudent();
    //derived class object is assigning to base class.. it is ok for the complier
    student = schoolStudent;
    
    //base class object is assigning to derived class... complier error
    schoolStudent = student;
    

2 个答案:

答案 0 :(得分:5)

1)您可以将派生对象类型指定给您的应用程序的scallablity基础。 实际类型仍然是派生的,但它在基类中的代码中呈现。您只对基本类型对象进行操作,因此不要在代码中包含所有不同的对象类型。为了顺利工作,您可以使用Polymorphism

Human h = new Student(); 

StudentMechanicDoctorKid都是Humans,因此这将成为Human为根的树。向后执行意味着将树向上滚动。谁是现在的根?您的代码层次结构中断

2)构造顺序从基类开始直到上一级。因此,在上面的示例中:首先将被称为Human的构造函数和Student之后的构造函数。

答案 1 :(得分:3)

为什么要写一个子类?要添加内容。不同的子类会添加不同的东西(或者你只需​​要一个)。如果您有对基类的引用,那么可能引用您想到的子类的实例,但它可能完全引用其他内容。然后会发生什么?您将尝试与对象甚至没有的功能进行交互。像JavaScript这样的动态语言允许你做这样的事情,但是像C#这样的强类型语言没有设计。在一个大型项目中,这非常有用。编译器一直关注着哪些地方,所以你作为程序员不必花费你的生命来编写需要弄清楚事物是什么的代码。

class Mammal {
    public void Nurse() { /* */ }
}

class Dog : Mammal {
    public void ChaseCar() { /* */ }
}

class Cat : Mammal {
    public void ClimbTree() { /* */ }
}

Mammal myPet = new Cat();

//  The actual object which myPet refers to may not be a Dog, so the 
//  compiler won't let you do this. The declared type of the reference, 
//  Mammal, is an implicit guarantee that, unless it's null, it's 
//  referring to something that can be treated as a Mammal. 
myPet.ChaseCar();

//  You can force it to try, but in this case, myPet does not refer
//  to a Dog, so this call will fail at runtime and throw an exception. 
((Dog)myPet).ChaseCar();

//  But C# does let you find out what you've really got. In this case, 
//  myPet is not Dog, so this block won't execute. But if it were a 
//  Dog, it would. In the general case, that can only be determined at 
//  runtime. In principle the compiler could make an exception for 
//  cases where the actual runtime type of myPet can be known at 
//  compile time -- as in this example code -- but my guess is that 
//  the compiler designers would see that as adding more complexity 
//  and confusion than it would be worth. 
if ( myPet is Dog ) {
    Dog myDog = myPet as Dog;
    myDog.ChaseCar();
}

考虑这种情况:任何人都可以将任何东西传递给这个方法。 animal实际上可能是BaboonGiraffe

public void CarDrivesBy(Mammal animal) {
    //  What is animal? At this point, you can't know, the compiler 
    //  can't know, so it won't accept this. 
    animal.ChaseCar();
}

如果您想将动物视为狗,您可以要求编译器帮助保证您获得Dog,然后将其视为具有(相对)置信度的动物:

public void CarDrivesBy(Dog animal) {
    //  Now the compiler knows what you want, and enforces that on 
    //  anybody who calls this method. 
    animal.ChaseCar();
}

另外,只是在术语上,“范围”这个词,因为它在编程中使用,指的是一个完全不相关的概念。

相关问题