首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >方法从继承类传递到基类。

方法从继承类传递到基类。
EN

Stack Overflow用户
提问于 2012-04-26 16:08:06
回答 2查看 209关注 0票数 1

我有预感我做错了。我刚开始学习抽象类,已经阅读了一些教程,但是我不知道如何将它应用到我的情况中。我认为我的设计可能有问题,但我想不出另一种方法。我的公司生产几台不同的电脑,我需要能够监控电池信息。虽然获取信息不是问题,但要想办法将不同的命令发送到基类以完成我需要它做的事情。说我想要我的1号手机电压。在一个单元上,命令是0x0418,在另一个单元上,命令是0x453。因此,在我的信息类中,我运行了一个测试,以了解模型是什么。我有一个名为电池的基类,它有许多变量是每个电池的标准变量(电池电压、充电ic、充电电流等),然后我决定为每个扩展电池的单元设置单独的类是很好的。

现在,我认为我对类的设计是正确的(可能是错误的,因为我不擅长抽象和多态性)。我有一个面板,它最终会显示我从BatteryInformation类获得的信息。类似于Battery1Cell1Label.Text = batteryInfo.GetCell1(1);Battery2Cell1Label = batteryInfo.GetCell1(2)。

因此,在我的基类中,我想我需要一个GetValue(字节命令)(因为它是一个嵌入式控制器命令来获取每种不同类型的信息)。也许我应该停止说话,把我所拥有的代码贴出来,告诉你我的错误。

battery.cs

代码语言:javascript
复制
public abstract class Battery<T> //not sure that the <T> is right
{
    public string Information { get; private set; }
    public float Cell1 { get; private set; }
    public float Cell2 { get; private set; }
    public float Cell3 { get; private set; }
    public float Cell4 { get; private set; }
    public int FCC { get; private set; }
    public bool ChargeIC { get; private set; }
    public int StartCharge { get; private set; }
    public int CurrentCharge { get; private set; }
    public bool Exists { get; private set; }

    protected internal void GetValue(byte command)
    {
        //Use Embedded controller to get said value
        //ECPort.ReadEC(command);
        //Testing Purposeses
        Console.WriteLine(command);
    }
}

Battery8800.cs

代码语言:javascript
复制
class Battery8800 : Battery<Battery8800>
{
    public Battery8800() : base()
    {

    }
    public void GetValue(BatteryCommands command)
    {
        base.GetValue((byte)command);
    }

    public enum BatteryCommands
    {
        Battery1VoltageHigh = 0x0402,
        Battery1VoltageLow = 0x0403,
        Batt1ChargeCurrentHigh = 0x0404,
        Batt1ChargeCurrentLow = 0x0405,
        Battery1MaxError = 0x0407,
        Battery1RSOC = 0x0409,
        Battery1FCCHigh = 0x040E,
        Battery1FCCLow = 0x040F,
        Battery1DCHigh = 0x0412,
        Battery1DCLow = 0x0413,
        Battery1Cell1High = 0x0418,
        Battery1Cell1Low = 0x0419,
        Battery1Cell2High = 0x041A,
        Battery1Cell2Low = 0x041B,
        Battery1Cell3High = 0x041C,
        Battery1Cell3Low = 0x041D,
        Battery1Cell4High = 0x041E,
        Battery1Cell4Low = 0x041F,
        PowerSource1 = 0x0420,
//many more commands for battery 2 etc etc
    }
}

BatteryInformation.cs

代码语言:javascript
复制
class BatteryInformation
{
    public Battery battery1; //error says it needs 1 type of argument
    public Battery battery2; //error says it needs 1 type of argument
    public BatteryInformation()
    {

        switch (UnitModel.GetModelEnum())
        {
            case UnitModel.DLIModel.DLI8300M:
                battery1 = new Battery8300();
                battery2 = new Battery8300();
                break;
            case UnitModel.DLIModel.DLI8400:
                battery1 = new Battery8400();
                battery2 = new Battery8400();
                break;
            case UnitModel.DLIModel.DLI8500:
                battery1 = new Battery8500();
                break;
            case UnitModel.DLIModel.DLI8500P:
                battery1 = new Battery8500P();
                break;
            case UnitModel.DLIModel.DLI8800:
                battery1 = new Battery8800();
                break;
            case UnitModel.DLIModel.DLI9200:
                battery1 = new Battery9200();
                break;
            default:
                break;
        }
        //for testing purposes
        battery1 = new Battery8800();
        battery1.DoThis(Battery8800.BatteryCommands.Batt1ChargeCurrentHigh);
    }
}

是的,为了省选秀!权力刚刚熄灭,我没有松懈,只有一句话!

所以,当我的电脑打开的时候,我在想在我的电池面板课上做这样的事情可能会更好。

代码语言:javascript
复制
    //in my timer_tick event
    BatteryInformation.UpdateBatteries();
    battery1Cell1Label.Text = BatteryInformation.Battery1.Cell1.ToString();
    //etc etc

但我仍然需要让它发挥作用,但我很难弄清楚如何进行抽象。谢谢您抽时间见我。

编辑

我想我走错路了。

代码语言:javascript
复制
class Battery1_8400 : Battery
{
    public override bool Update()
    {
        //TODO finish
        Exists = GetValue((ushort)Commands.PowerSource) != 0xFF;
        if (Exists)
        {
            Cell1 = GetValue((ushort)Commands.Cell1Low, (ushort)Commands.Cell1High) / 1000.0f;
            Cell2 = GetValue((ushort)Commands.Cell2Low, (ushort)Commands.Cell2High) / 1000.0f;
            Cell3 = GetValue((ushort)Commands.Cell3Low, (ushort)Commands.Cell3High) / 1000.0f;
            FCC = GetValue((ushort)Commands.FCCLow, (ushort)Commands.FCCHigh);
            Voltage = GetValue((ushort)Commands.VoltageLow, (ushort)Commands.VoltageHigh);
            return true;
        }
        else
        {
            return false;
        }
    }
    private enum Commands
    {
        PowerSource = 0x0480,
        Charge = 0x0432,
        RSOC = 0x0734,
        DCLow = 0x0402,
        DCHigh = 0x0403,
        FCCLow = 0x0404,
        FCCHigh = 0x0405,
        MaxError = 0x0730,
        Cell1Low = 0x0778,
        Cell1High = 0x0779,
        Cell2Low = 0x077C,
        Cell2High = 0x077D,
        Cell3Low = 0x0780,
        Cell3High = 0x0781,
        VoltageLow = 0x0438,
        VoltageHigh = 0x0439,
        ChargeCurrentLow = 0x0728,
        ChargeCurrentHigh = 0x0729,
        ChargeIC = 0x1A03,
    }
}

我有9个文件,它们在更新命令的工作方式上都是相同的。每个类的命令略有不同。看看batter2_8400.cs的枚举

代码语言:javascript
复制
    private enum Commands
    {
        PowerSource = 0x0480,
        Charge = 0x04C2,
        RSOC = 0x0834,
        DCLow = 0x0492,
        DCHigh = 0x0493,
        FCCLow = 0x0494,
        FCCHigh = 0x0495,
        MaxError = 0x0830,
        Cell1Low = 0x0878,
        Cell1High = 0x0879,
        Cell2Low = 0x087C,
        Cell2High = 0x087D,
        Cell3Low = 0x0880,
        Cell3High = 0x0881,
        VoltageLow = 0x04C8,
        VoltageHigh = 0x04C9,
        ChargeCurrentLow = 0x0828,
        ChargeCurrentHigh = 0x0829,
        ChargeIC = 0x1A04,
    }

update命令在该文件和其他7个文件中是相同的。对我来说这似乎是个糟糕的设计,但我不知道该怎么做。顺便说一句,这就是我的课程在给出的一个答案和收到的少数评论之后的样子。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-04-27 18:17:34

最后我想我知道该怎么做了。在我看来是干净的,似乎很有道理。也许你能批评一下?

代码语言:javascript
复制
public abstract class Battery
{
    public string Information { get; set; }
    public float Cell1 { get {return GetValue(Cell1Low, Cell1High) / 1000.0f;} }
    public float Cell2 { get {return GetValue(Cell2Low, Cell2High) / 1000.0f;} }
    public float Cell3 { get {return GetValue(Cell3Low, Cell3High) / 1000.0f;} }
    public float Cell4 { get {return GetValue(Cell4Low, Cell4High) / 1000.0f;} }
    public float Voltage { get {return GetValue(VoltageLow, VoltageHigh);} }
    public int DC { get {return GetValue(DCLow, DCHigh);} }
    public int FCC { get {return GetValue(FCCLow, FCCHigh);} }
    //public bool ChargeIC { get {return } }
    //public int StartCharge { get {return } }
    //public int CurrentCharge { get {return } }
    public bool Exists { get {return GetValue(PowerSource) != 0xFF} }
    public int FCCPercent { get {return ((FCC * 100) / DC);} }

    /// <summary>
    /// Gets a value depending on the Embedded controller
    /// </summary>
    /// <param name="low">The low byte command to process</param>
    /// <param name="high">The high byte command to process</param>
    /// <returns></returns>
    private int GetValue(ushort low, ushort high)
    {
        //Use Embedded controller to get said value
        //ECPort.ReadEC(command);
        //Testing Purposeses
        var lowValue = ECPort.ReadEC(low);
        var highValue = ECPort.ReadEC(high);
        return (int)((highValue << 8) + lowValue);
    }

    private int GetValue(ushort command)
    {
        return (int)ECPort.ReadEC(command);
    }

    public abstract ushort PowerSource {get;}
    public abstract ushort Charge{get;}
    public abstract ushort RSOC{get;}
    public abstract ushort DCLow{get;}
    public abstract ushort DCHigh{get;}
    public abstract ushort FCCLow{get;}
    public abstract ushort FCCHigh{get;}
    public abstract ushort MaxError{get;}
    public abstract ushort Cell1Low{get;}
    public abstract ushort Cell1High{get;}
    public abstract ushort Cell2Low{get;}
    public abstract ushort Cell2High{get;}
    public abstract ushort Cell3Low{get;}
    public abstract ushort Cell3High{get;}
    public abstract ushort Cell4Low { get; }
    public abstract ushort Cell4High { get; }
    public abstract ushort VoltageLow{get;}
    public abstract ushort VoltageHigh{get;}
    public abstract ushort ChargeCurrentLow{get;}
    public abstract ushort ChargeCurrentHigh{get;}
    public abstract ushort ChargeIC{get;}

}

然后,在继承它的子类上,一个例子是

代码语言:javascript
复制
class Battery1_8400 : Battery
{
    public override ushort PowerSource { get {return 0x0480;}}
    public override ushort Charge { get {return  0x0432;}}
    public override ushort RSOC { get {return  0x0734;}}
    public override ushort DCLow { get {return  0x0402;}}
    public override ushort DCHigh { get {return  0x0403;}}
    public override ushort FCCLow { get {return  0x0404;}}
    public override ushort FCCHigh { get {return  0x0405;}}
    public override ushort MaxError { get {return  0x0730;}}
    public override ushort Cell1Low { get {return  0x0778;}}
    public override ushort Cell1High { get {return  0x0779;}}
    public override ushort Cell2Low { get {return  0x077C;}}
    public override ushort Cell2High { get {return  0x077D;}}
    public override ushort Cell3Low { get {return  0x0780;}}
    public override ushort Cell3High { get {return  0x0781;}}
    public override ushort VoltageLow { get {return  0x0438;}}
    public override ushort VoltageHigh { get {return  0x0439;}}
    public override ushort ChargeCurrentLow { get {return  0x0728;}}
    public override ushort ChargeCurrentHigh { get {return  0x0729;}}
    public override ushort ChargeIC { get {return  0x1A03;}}
}

现在,我所要做的就是编辑一个文件battery.cs,如果我需要对它进行更改。

票数 0
EN

Stack Overflow用户

发布于 2012-04-26 16:28:38

基类BatteryInformation对于需要检索的每个值都应该具有抽象属性,如下所示:

代码语言:javascript
复制
public abstract class BatteryInfo {
    // int should be replaced with the actual data type of the value
    public abstract int VoltageHigh { get; }
    public abstract int VoltageLow { get; }
    // etc. for each value you need
}

然后在您的子类中实现每个属性。

代码语言:javascript
复制
public class Battery8800 : BatteryInfo {
    public override int VoltageHigh {
        get {
          int value;
          // do code to retrieve value
          return value;
        }
    }
}

此外,我将提供一个您的UI可以使用的方法,如下所示:

代码语言:javascript
复制
 public IEnumerable<BatteryInfo> GetAllBatteryInfo() {
   // get each battery
 }

这样,用户界面就不需要担心如何检索每个电池的电池信息。这允许您使用列表或网格样式控件之一查看电池信息。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10337220

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档