我需要知道在执行以下代码时屏幕后面发生了什么

时间:2012-04-09 07:09:53

标签: c#

类--- A

class ClassA
{
    public string c1()
    {
        return "Class-A";
    }

}

类---乙

class ClassB:ClassA
{
    public string c2()
    {
        return "Class-B";
    }
}

主类

-----第1部分------------------

 ClassA obj1 = new ClassB();
 string a = obj1.c1();//Here i will get only c1
 Console.WriteLine(a);
 Console.ReadLine();

-----第2部分------------------

 ClassB obj1 = new ClassA();
 string a = obj1.c2();//Her i will get both c1 and c2
 Console.WriteLine(a);
 Console.ReadLine();

在第1部分中,我将只获得c1.I需要知道是否为堆栈中的ClassA创建了变量(obj)并从<分配了ClassB的地址strong>堆。实际发生了什么?

在第2部分中,获取(编译错误)转换错误。执行此代码时屏幕后面实际发生了什么。

谢谢, Joby Kurian

4 个答案:

答案 0 :(得分:5)

第1部分

ClassA obj1 = new ClassB();

这将创建ClassB实例 - 一个对象。

它还声明了一个名为obj1变量,类型为ClassA。该变量的将始终为引用 - null或对ClassA实例的引用。在这种情况下,初始值是对新创建的ClassB对象的引用。 (对ClassB对象的引用也可以用作ClassA引用,因为ClassB派生自ClassA。)

当您致电c1时,它只是调用ClassA中的实现 - 但在该方法中,如果您打印出this.GetType(),它仍会返回ClassB的类型,因为它在ClassB对象内“操作”。

我强烈建议您不要担心堆栈和堆。专注于三个不同的概念

  • 物件
  • 引用(导航到对象的方式,或null)
  • 变量(命名存储位置)

Eric Lippert在博客上发表了关于此类事情的很多。您可能希望从The Stack Is An Implementation Detail开始。

第2部分

ClassB obj1 = new ClassA();

这将创建ClassA的实例,并尝试将对象的引用分配给类型为ClassB的变量。这不起作用,因为ClassA 派生自ClassB。您不能将编译时类型ClassA的引用用于类型为ClassB的变量。作为为什么的演示,这不起作用,这有点像这样做:

string x = new object();
Console.WriteLine(x.Length); // What could this possibly print out?

基本上,继承不会那么循环 - 您可以将ClassB的实例视为ClassA的实例(在大多数情况下),但不能ClassA的实例视为ClassB的实例。您通常会在ClassB中添加更多状态(字段),因此ClassA的实例中不会出现这些信息。

答案 1 :(得分:0)

发生的事情(在第二部分中)是你试图将A类实例化为B类的变量。这是不可能的,因为变量必须具有可在instanciated对象中访问的可用属性。因此,当您尝试调用方法c2()时,它在对象中是不存在的。另一种方法可以正常工作,因为变量的所有可用属性和方法都存在于实例化对象中。

答案 2 :(得分:0)

您正在创建类A的对象,并且调用类B的构造函数创建该特定类的对象,然后访问这些属性。你为什么要为你感兴趣的东西!

答案 3 :(得分:0)