基类=新派生类。这是如何运作的?

时间:2015-10-14 17:12:14

标签: c# class

假设我有一个名为Enemy的基类和一个名为Ogre的派生类。

以下两种方式创建实例有什么区别:

Enemy newOgre = new Ogre();

Ogre newOgre = new Ogre();

5 个答案:

答案 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(),您可以访问基类和派生类的方法