简体   繁体   English

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

[英]Base Class = New Derived Class. How does this work?

Say I have a base class called Enemy and a derived class called Ogre. 假设我有一个名为Enemy的基类和一个名为Ogre的派生类。

What is the difference between creating an instance these two ways: 这两种方式创建实例有什么区别:

Enemy newOgre = new Ogre();

Ogre newOgre = new Ogre();

Actually, the piece of code that is creating the instance is only new Ogre() . 实际上,创建实例的代码片段只是new Ogre() What is in the left side of the equal sign has nothing to do with creating the instance. 等号左侧的内容与创建实例无关。

The first statement is simply assigning the created instance to a variable of type Enemy . 第一个语句只是将创建的实例分配给Enemy类型的变量。 The second one is assigning it to a variable of type Ogre . 第二个是将它分配给Ogre类型的变量。

So you have two variables of different types pointing to objects of the same type, ie Ogre . 所以你有两个不同类型的变量指向同一类型的对象,即Ogre

The variable (what is on the left side of the equal sign), only determines what you can access from the object. 变量(等号左侧的变量)仅确定您可以从对象访问的内容。 For example, if the Ogre class has a method that is not inherited from Enemy , then using the Enemy variable, you will not be able to access it. 例如,如果Ogre类的方法不是从Enemy继承的,那么使用Enemy变量,您将无法访问它。

Please note that the variable does not effect how the object behave. 请注意,该变量不会影响对象的行为方式。 For example, if Ogre overrides a method defined in Enemy that does something different. 例如,如果Ogre重写了Enemy中定义的不同的方法。 Calling this method on an instance of Ogre using a variable of type Enemy would cause the overridden method in Ogre to be invoked, not the one in Enemy , 使用Enemy类型的变量在Ogre实例上调用此方法将导致调用Ogre的重写方法,而不是Enemy

For example, consider these classes: 例如,考虑以下类:

public class Enemy
{
    public virtual void Test()
    {
        Console.WriteLine("enemy");
    }
}

public class Ogre: Enemy
{
    public override void Test()
    {
        Console.WriteLine("ogre");
    }
}

Now if you do this: 现在,如果你这样做:

Orge enemy = new Orge();
enemy.Test();

The console would print "ogre". 控制台会打印“食人魔”。

And if you do this: 如果你这样做:

Enemy enemy = new Ogre();
enemy.Test();

The console would still print "orge". 控制台仍然会打印“orge”。

In addition to Yacoub's answer, in this case, Enemy would not contain the properties, and methods that Ogre has. 除了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; }
}

Let's say you inherit Enemy in your Ogre class. 假设您在Ogre课程中继承了敌人。 This mean that your Ogre will effectively contain 3 properties: 1,2 and 3. 这意味着你的食人魔将有效地包含3个属性:1,2和3。

In your example you're assigning an Ogre to an Enemy type. 在您的示例中,您将Ogre分配给Enemy类型。 The Enemy type doesn't contain a "Property3" and therefor you won't be able to work with the extended class " Ogre " in an Enemy cast object. Enemy类型不包含“Property3”,因此您将无法使用Enemy强制转换对象中的扩展类“ Ogre ”。

//This will work
Ogre newOgre = new Ogre();
int newInt = newOgre.Property3;

//This wont.
Enemy newOgre = new Ogre();
int newInt = newOgre.Property3;

One declares a variable of type Enemy and references a new Ogre object. 一个声明Enemy类型的变量并引用一个新的Ogre对象。 The other declares a variable of type Ogre and references a new Ogre object. 另一个声明一个Ogre类型的变量并引用一个新的Ogre对象。

Some differences (not an exhaustive list): 一些差异(不是详尽的清单):

  • You can't call non-inherited methods of Ogre on the variable of type Enemy . 你不能在Enemy类型的变量上调用Ogre非继承方法。
  • Any virtual methods of Enemy that are overridden in Ogre will use Ogre's implementation when called on either variable. Ogre中重写的任何Enemy虚拟方法都会在调用任一变量时使用Ogre's实现。

Here 这里

Enemy newOgre = new Ogre();

you can't call method using newOgre that was later added to the class Ogre for example and was not in the base class, whereas using the other variable you can call those methods. 你不能使用后来添加到类Ogre newOgre来调用方法,而不是在基类中,而使用另一个变量可以调用这些方法。

Assume your Enemy class looks like this: 假设您的Enemy类看起来像这样:

public class Enemy
{
    public void Attack() { }
    public void Move() { }
}

and your Ogre class like this: 和你的Ogre类是这样的:

public class Ogre : Enemy
{
    public void OgreSmash() { }
}

With the Enemy variable you would only have access to Attack() and Move() but not to the OgreSmash() with the Ogre variable you will have access to the methods of the base and derived class. 使用Enemy变量,您只能访问Attack()Move()但不能访问带有Ogre变量的OgreSmash() ,您可以访问基类和派生类的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM