假设我有一个名为Enemy的基类和一个名为Ogre的派生类.
这两种方式创建实例有什么区别:
Enemy newOgre = new Ogre();
Ogre newOgre = new Ogre();
Run Code Online (Sandbox Code Playgroud)
Yac*_*sad 10
实际上,创建实例的代码片段只是new Ogre().等号左侧的内容与创建实例无关.
第一个语句只是将创建的实例分配给类型的变量Enemy.第二个是将它分配给一个类型的变量Ogre.
所以你有两个不同类型的变量指向同一类型的对象,即Ogre.
变量(等号左侧的变量)仅确定您可以从对象访问的内容.例如,如果Ogre类具有不从中继承的方法Enemy,则使用该Enemy变量,您将无法访问它.
请注意,该变量不会影响对象的行为方式.例如,如果Ogre覆盖定义的方法,则会Enemy执行不同的操作.在Ogre使用类型变量的实例上调用此方法Enemy将导致Ogre调用重写的方法,而不是调用的方法Enemy,
例如,考虑以下类:
public class Enemy
{
public virtual void Test()
{
Console.WriteLine("enemy");
}
}
public class Ogre: Enemy
{
public override void Test()
{
Console.WriteLine("ogre");
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果你这样做:
Orge enemy = new Orge();
enemy.Test();
Run Code Online (Sandbox Code Playgroud)
控制台会打印"食人魔".
如果你这样做:
Enemy enemy = new Ogre();
enemy.Test();
Run Code Online (Sandbox Code Playgroud)
控制台仍然会打印"orge".
除了Yacoub的回答,在这种情况下,Enemy不会包含Ogre的属性和方法.
public class Enemy
{
public int Property1 { get; set; }
public int Property2 { get; set; }
}
public class Ogre : Enemy
{
public int Property3 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
假设您在Ogre课程中继承了敌人.这意味着你的食人魔将有效地包含3个属性:1,2和3.
在您的示例中,您将分配Ogre一个Enemy类型.Enemy类型不包含"Property3",因此您将无法使用强制转换对象中的扩展类" Ogre" Enemy.
//This will work
Ogre newOgre = new Ogre();
int newInt = newOgre.Property3;
//This wont.
Enemy newOgre = new Ogre();
int newInt = newOgre.Property3;
Run Code Online (Sandbox Code Playgroud)