问题描述
我有一个简单的问题.假设我有两个类似下面的类.
Hi,
I have a simple question. Suppose I have two classes like below.
class Room
{}
class LivingRoom : Room
{
int p1;
public void Method()
{
}
}
并假设我在主程序中创建了LivingRoom类的新实例,并将其分配给Room.
And suppose I am creating a new instance of class LivingRoom in my main program and assigning it to Room.
static void Main(string[] args)
{
Room r1 = new LivingRoom();
Console.ReadLine();
}
创建LivingRoom实例时,内存中至少应有未分配的指向LivingRoom对象的属性p1和方法Method()的指针.但是Room类中没有相应的属性和方法.基类中没有这样的属性和方法,是否应该没有错误? Room类中没有指针,也没有属性来保存继承的类LivingRoom中存在的内容?
问候,
When a LivingRoom instance is created, there should be at least unassigned pointers to property p1 and method Method() of LivingRoom object in the memory. But there are no corresponding properties and methods in Room class. Should not there be an error as there are not such properties and method in the base class ? There is no pointer in Room class or a property to hold what exists in the inherited class LivingRoom ?
Regards,
推荐答案
using System;
namespace ConsoleTester
{
public class Room
{
public int r;
}
public class LivingRoom : Room
{
public int p1;
public void Method()
{
}
}
class Program
{
static void Main(string[] args)
{
Room r1 = new LivingRoom();
r1.r = 14; // Compiler is happy
r1.p1 = 14; // Compiler complains: "Room does not contain a definition of p1"
((LivingRoom) r1).p1 = 14; //Compiler is happy.
Console.ReadLine();
}
}
}
问题出在转换上.当r1转换为继承类型时,它必须持有对LivingRoom对象的Method()的引用.它只是隐藏的并不意味着不存在对该引用的引用.这个正确吗?"
不完全是:您在想错了.
"r1"始终保持对房间的引用.它不知道Room类之外的任何内容.它实际上拥有对LivingRoom实例的引用与它无关:它甚至不知道LivingRooms存在! LivingRoom实例具有成为LivingRoom所需的所有信息,以及成为Room的所有信息.
"The problem is in casting. When r1 is cast to inherited type, it must be holding a reference to the Method() of LivingRoom object. That it is just hidden does not mean that there exists no reference to it. Is this correct ?"
Not really: you are thinking about it wrong.
"r1" holds a reference to a Room all the time. It doesn''t know about anything outside the Room class. That it actually holds a reference to a LivingRoom instance is irrelevant to it: it doesn''t even know that LivingRooms exist! The LivingRoom instance has all the info it needs to be a LivingRoom, as well as all the info to be a Room.
class MyBaseClass { internal byte somethingOld; }
class MyDerivedClass : MyBaseClass { internal int somethingNew; }
MyBaseClass b = //the variable is of complile-time class MyBaseClass
new MyDerivedClass(); //
bool isDerived = b is MyDerivedClass; //returns true
//can be down-casted:
MyDerivedClass derived = b as MyDerivedClass; //could be null, but it is not
isDerived = derived != null; //still true
derived.somethingNew = 13; //will work
您的指针"术语对于.NET是不正确的,但是让我们对此稍作猜测:在某种程度上,您可以将.NET引用作为指针".该实例指向一个内存块.创建MyBaseClass
的实例时,此块中只有somethingOld
,而没有somethingNew
.创建派生类时,内存块看起来完全一样,但是somethingNew
附加到了它.变量指向统一的内存块.从变量b
的角度来看,它指向较小的块,但同时它指向扩展的内存块;公用部分与MyBaseClass
相同.
You "pointer" terminology is incorrect for .NET, but let''s forger about it for a while: you can thing of .NET references as of "pointers", to a certain point. The instance points to a block of memory. When you create an instance of MyBaseClass
, you have only somethingOld
in this block, not somethingNew
. When you create derived class, the block of memory looks exactly the same, but somethingNew
is appended to it. A variables point to united block of memory. From the standpoint of the variable b
it points to smaller block, but at the same time it points to extended block of memory; common part is the same as that of MyBaseClass
.
这篇关于分配给继承类时为继承类型分配内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!