C# 在抽象类方法中将实例化的类成员用作变量

C# 在抽象类方法中将实例化的类成员用作变量,c#,class,inheritance,abstract,C#,Class,Inheritance,Abstract,我试图弄清楚如何在一个基本抽象类中创建一个能够使用从该类派生的实例化对象的成员值的方法。例如,假设我有一个名为Vehicle的类,它继承了一个名为IVehicle的接口 public abstract class Vehicle : IVehicle { public int Wheels = 4; public int CountWheels() { return Wheels; } } 假设我有另一个名为摩托车的类,它继承了车辆本身 pub

我试图弄清楚如何在一个基本抽象类中创建一个能够使用从该类派生的实例化对象的成员值的方法。例如,假设我有一个名为
Vehicle
的类,它继承了一个名为
IVehicle
的接口

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

    public int CountWheels()
    {
        return Wheels;
    }
}
假设我有另一个名为摩托车的类,它继承了车辆本身

public class Motorcycle : Vehicle, IVehicle
{
    public int Wheels = 2;
}
如果我制作了一辆名为
newMotorcycle
的新
Motorcycle
,并调用
newMotorcycle.CountWheels()
,我得到的是4而不是2。我假设这是我在
Motorcycle
类中的
Wheels
定义的问题,但我已经尝试了我能想到的一切来实现这一点,它似乎总是想忽略子类定义。我知道我可以将
CountWheels()
方法抽象出来,并在
Motorcycle
类中定义它,但我正试图使基本
Vehicle
类尽可能通用,这样我就可以实现大量其他子类,而不必反复重新定义相同的方法

我的第一个问题;我想做的事可能吗?如果是这样的话,我的成员定义的哪一部分需要改变,才能按照我的预期工作


我保证在我发布这篇文章之前我搜索了互联网,但我找不到足够的信息来帮助我自己…

你需要让
轮子
成员
虚拟
并覆盖
它,否则你只是“隐藏”基础成员。您还需要将其更改为一个属性,以使其
虚拟化

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; } }
}

您需要使
Wheels
成员
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; } }
}

查找
virtual
属性和方法()

您需要
Wheels
在base中成为
public-virtual-int-Wheels{get;set;}
,在派生中成为
public-override-int-Wheels{get;set;}


然后,您可以根据需要在每个类中初始化值。

查找
virtual
属性和方法()

您需要
Wheels
在base中成为
public-virtual-int-Wheels{get;set;}
,在派生中成为
public-override-int-Wheels{get;set;}


然后,您可以根据需要在每个类中初始化该值。

您会注意到,您发布的代码中有一条警告:

摩托车。轮子隐藏着一辆车。轮子

因此,您的问题是,
Vehicle
不知道派生类隐藏了它的一个成员(因此为什么隐藏是个坏主意)

由于不能有虚拟字段,因此应将其更改为虚拟(或在本例中为抽象,因此每个人都必须定义它)属性:


现在,每个派生类都必须有一个基类可以使用的
Wheels
属性。

您会注意到您发布的代码中有一个警告:

摩托车。轮子隐藏着一辆车。轮子

因此,您的问题是,
Vehicle
不知道派生类隐藏了它的一个成员(因此为什么隐藏是个坏主意)

由于不能有虚拟字段,因此应将其更改为虚拟(或在本例中为抽象,因此每个人都必须定义它)属性:


现在,每个派生类都必须具有基类可以使用的
Wheels
属性。

这里是另一个选项。您可以将
车轮
定义为普通属性,然后在
摩托车
的构造函数中设置,而不是将
车轮
定义为
车辆
上的虚拟属性,并覆盖
摩托车
上的该属性:

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;
    }
}

这是另一个选择。您可以将
车轮
定义为普通属性,然后在
摩托车
的构造函数中设置,而不是将
车轮
定义为
车辆
上的虚拟属性,并覆盖
摩托车
上的该属性:

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;
    }
}

你为什么需要轮子和计数轮?例如,您可以在Vehicle.countWheels中返回4作为默认值,然后覆盖Motorcycle.countWheels并返回2。然后拆下车轮。举个例子…@ElDuderino有人可能会猜测这是一个MCVE,而他的真实代码设计较少。为什么你需要轮子和计数轮?例如,您可以在Vehicle.countWheels中返回4作为默认值,然后覆盖Motorcycle.countWheels并返回2。然后拆下车轮。仅仅是一个例子…@ElDuderino有人可以猜测这是一个MCVE,他的真实代码设计得不多,我很欣赏。我注意到了警告,并试图纠正它,但走错了方向。感谢您的迅速回复!我很感激。我注意到了警告,并试图纠正它,但走错了方向。感谢您的迅速回复!