简体   繁体   English

在抽象类方法中使用实例化的类成员作为变量

[英]Using instantiated class members as variables in abstract class methods

I'm trying to figure out how to make a method in a base abstract class capable of using member values of instantiated objects derived from the class. 我试图弄清楚如何在基本抽象类中创建一种方法,该方法能够使用从该类派生的实例化对象的成员值。 For example, let's say I have a class called Vehicle that inherits an interface called IVehicle ; 例如,假设我有一个名为Vehicle的类,该类继承了一个名为IVehicle的接口;

public abstract class Vehicle : IVehicle
{
    public int Wheels = 4;

    public int CountWheels()
    {
        return Wheels;
    }
}

Let's say I then had another class called Motorcycle that inherited Vehicle as such; 假设我还有另一个类名为Motorcycle类,它继承了Vehicle

public class Motorcycle : Vehicle, IVehicle
{
    public int Wheels = 2;
}

If I make a new Motorcycle called newMotorcycle and I call newMotorcycle.CountWheels() , I get 4 instead of 2. I'm assuming this is an issue with my Wheels definition in the Motorcycle class, but I've tried just about everything I can think of to get this to work and it always seems to want to ignore child class definitions. 如果我制作了一个名为newMotorcycle的新Motorcycle并且我将其newMotorcycle.CountWheels() ,则得到4而不是2。我假设这是Motorcycle类中Wheels定义的问题,但是我已经尝试了所有方法可以想到使它起作用,并且似乎总是想忽略子类定义。 I know that I could make the CountWheels() method abstract and define it in the Motorcycle class, but I'm trying to keep the base Vehicle class as generic as possible so I can implement a ton of other child classes without having to redefine the same method over and over. 我知道我可以使CountWheels()方法成为抽象并在Motorcycle类中对其进行定义,但是我试图使Vehicle类基本类尽可能通用,这样我就可以实现大量其他子类,而不必重新定义一遍又一遍相同的方法。

My first question; 我的第一个问题; is what I'm trying to do even possible? 是我什至试图做的事情? If so, what part of my member definition needs to change for this to work the way I'm intending for it to? 如果是这样,我的成员定义的哪一部分需要更改才能使其按照我打算的方式工作?

I promise I scoured the internet before I posted this here and I couldn't find enough information to help myself... 我保证在我将其发布在这里之前,我会搜索过互联网,但找不到足够的信息来帮助自己...

You will notice that there is a warning in the code you posted: 您会注意到发布的代码中有一个警告:

Motorcycle.Wheels hides inherited member Vehicle.Wheels... Motorcycle.Wheels隐藏了继承的Vehicle.Wheels ...

Hence your problem, Vehicle has no idea that a derived class has hidden one of its members (hence why hiding is a bad idea). 因此,您的问题是Vehicle不知道派生类已隐藏其成员之一(因此,隐藏是一个坏主意)。

Since you can't have virtual fields, you should change it to a virtual (or in this case, abstract so everyone has to define it) property : 由于您没有虚拟字段,因此应将其更改为虚拟(或在这种情况下为抽象,因此每个人都必须定义) 属性

public abstract class Vehicle : IVehicle
{
    public abstract int Wheels {get;}

    public int CountWheels()
    {
        return Wheels;
    }
}

public class Motorcycle : Vehicle, IVehicle
{
    public int Wheels => 2;
}

Now every derived class will have to have a Wheels property that the base class can use. 现在,每个派生类都必须具有基类可以使用的Wheels属性。

You need to make the Wheels member virtual and override it, otherwise you're just "hiding" the base member. 您需要将Wheels成员设为virtualoverride它,否则,您只是“隐藏”基础成员。 You'll also need to change it to a property in order to make it virtual : 您还需要将其更改为属性以使其virtual

public abstract class Vehicle 
{
    public virtual int Wheels { get { return 4; } }

    public int CountWheels()
    {
        return Wheels;
    }
}

public class Motorcycle : Vehicle
{
    public override int Wheels { get { return 2; } }
}

Look up virtual properties and methods ( https://msdn.microsoft.com/en-us/library/9fkccyh4.aspx ) 查找virtual属性和方法( https://msdn.microsoft.com/zh-cn/library/9fkccyh4.aspx

You need Wheels to be public virtual int Wheels {get; set;} 您需要Wheels才能成为public virtual int Wheels {get; set;} public virtual int Wheels {get; set;} in base and public override int Wheels {get; set;} public virtual int Wheels {get; set;}在基本和public override int Wheels {get; set;} public override int Wheels {get; set;} in derived public override int Wheels {get; set;}中的派生

Then you can initialize the value as you need in each class. 然后,您可以在每个类中根据需要初始化值。

Here's another option. 这是另一个选择。 Rather than defining Wheels as a virtual property on Vehicle , and overriding that property on Motorcycle , you can define Wheels as an ordinary property and then set it in the constructor for Motorcycle : 您可以将Wheels定义为普通属性,然后在Motorcycle的构造函数中设置它,而不是将Wheels定义为Vehicle的虚拟属性,并覆盖Motorcycle该属性:

public abstract class Vehicle : IVehicle
{
    public int Wheels { get; protected set; }

    public Vehicle()
    {
        Wheels = 4;
    }

    public int CountWheels()
    {
        return Wheels;
    }
}

public class Motorcycle : Vehicle, IVehicle
{
    public Motorcycle()
    {
        Wheels = 2;
    }
}

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

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