我需要知道在执行以下代码时屏幕后面发生了什么
本文关键字:屏幕 代码 什么 发生了 执行 | 更新日期: 2023-09-27 18:30:40
Class---A
class ClassA
{
public string c1()
{
return "Class-A";
}
}
班级---B
class ClassB:ClassA
{
public string c2()
{
return "Class-B";
}
}
主类
-----第一部分------------------
ClassA obj1 = new ClassB();
string a = obj1.c1();//Here i will get only c1
Console.WriteLine(a);
Console.ReadLine();
-----第二部分------------------
ClassB obj1 = new ClassA();
string a = obj1.c2();//Her i will get both c1 and c2
Console.WriteLine(a);
Console.ReadLine();
在第 1 部分中,我将只得到 c1。我需要知道是否在堆栈中为 A类创建了变量 (obj),并从堆中分配了 B 类的地址。到底发生了什么?
在第-2部分中,获取(编译错误)转换错误。执行此代码时屏幕后面实际发生的情况。
谢谢乔比·库里安
1 部分
ClassA obj1 = new ClassB();
这将创建ClassB
的实例 - 一个对象。
它还声明了一个名为 obj1
的变量,类型为 ClassA
。该变量的值将始终是引用 - null
或对ClassA
实例的引用。在这种情况下,初始值是对新创建的ClassB
对象的引用。(对ClassB
对象的引用也可以用作ClassA
引用,因为ClassB
派生自ClassA
。
当你调用c1
时,它只是在ClassA
中调用实现 - 但在该方法中,如果你打印出this.GetType()
它仍然会返回ClassB
的类型,因为它在ClassB
对象中"运行。
我强烈建议您不要担心堆栈和堆。专注于三个不同的概念:
- 对象
- 引用(导航到对象的方式,或 null)
- 变量(命名存储位置)
埃里克·利珀特(Eric Lippert)在博客上写了很多关于这类事情的文章。您可能希望从堆栈是实现细节开始。
第 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
的实例中。
发生的情况(在第二部分中)是你试图将类 A 实例化为类 B 的变量。无法执行此操作,因为变量必须具有可在实例化对象中访问的可用属性。因此,当您尝试调用方法 c2() 时,它在对象中不存在。反之则工作正常,因为变量的所有可用属性和方法都存在于实例化对象中。
正在创建类 A 的对象,并调用类 B 的构造函数创建该特定类伙伴的对象,然后访问属性。你为什么要对你感兴趣!