假设我有一个名为Enemy的基类和一个名为Ogre的派生类。
以下两种方式创建实例有什么区别:
Enemy newOgre = new Ogre();
Ogre newOgre = new Ogre();
答案 0 :(得分: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");
}
}
现在,如果你这样做:
Orge enemy = new Orge();
enemy.Test();
控制台会打印" ogre"。
如果你这样做:
Enemy enemy = new Ogre();
enemy.Test();
控制台仍会打印" orge"。
答案 1 :(得分:9)
除了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; }
}
让我们说你在你的食人魔班中继承了敌人。这意味着你的食人魔将有效地包含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;
答案 2 :(得分:2)
一个声明类型为Enemy
的变量并引用一个新的Ogre
对象。另一个声明了Ogre
类型的变量,并引用了一个新的Ogre
对象。
一些差异(不是详尽的清单):
Ogre
类型的变量上调用Enemy
的非继承方法。 Enemy
中被覆盖的Ogre
的任何虚拟方法在调用任一变量时都将使用Ogre's
实现。答案 3 :(得分:1)
下面
Enemy newOgre = new Ogre();
您无法使用稍后添加到类newOgre
的{{1}}来调用方法,而不是在基类中,而使用其他变量则可以调用这些方法。
答案 4 :(得分:1)
假设您的敌人类看起来像这样:
public class Enemy
{
public void Attack() { }
public void Move() { }
}
和你的Ogre类是这样的:
public class Ogre : Enemy
{
public void OgreSmash() { }
}
使用Enemy变量,您只能访问Attack()
和Move()
,但不能访问带有Ogre变量的OgreSmash()
,您可以访问基类和派生类的方法