简体   繁体   English

继承类的方法传递给基类

[英]methods from inherited class passed to base class

I have a feeling I'm doing this wrong. 我感觉自己做错了。 I'm new to abstract classes and such and have been reading tutorials for a little bit, but I can't figure out how to apply it to my situation. 我是抽象类之类的新手,并且已经阅读了一些教程,但是我不知道如何将其应用于我的情况。 I think that my design might be faulty but I can't think of another way to do it. 我认为我的设计可能有错误,但我想不出另一种方法来做。 My company makes a few different computers and I need to be able to monitor the battery information. 我公司生产了几台不同的计算机,我需要能够监视电池信息。 Although getting the information is not the problem, figuring out how to send the different commands to the base class to do what i need it to do. 尽管获取信息不是问题,但要弄清楚如何将不同的命令发送到基类以执行我需要它执行的操作。 Say I want to get my cell 1 voltage. 假设我要获得电池1的电压。 On one unit the command is 0x0418, on another it is 0x453. 在一个单元上,该命令为0x0418,在另一个单元上,该命令为0x453。 So in my information class I run a test to see what the model is. 因此,在我的信息课中,我运行了一个测试以查看模型是什么。 I have a Base class called battery that has a bunch of variables that are standard for each battery (cell voltage, charge ic, charging current etc etc) I then decided it would be good to make individual classes for each of my units that extends Battery. 我有一个称为Battery的基本类,它具有一堆变量,这些变量是每个电池的标准变量(电池电压,充电ic,充电电流等),然后我决定对扩展电池的每个单元都进行单独的分类会很好。

Now my design of the classes I think is spot on (could be wrong as I am not good at abstraction and polymorphism). 现在,我认为该类的设计是正确的(可能是错误的,因为我不擅长抽象和多态性)。 I have a panel that in the end would display the information that I get from the BatteryInformation class. 我有一个面板,最后将显示从BatteryInformation类获得的信息。 something like Battery1Cell1Label.Text = batteryInfo.GetCell1(1); 类似于Battery1Cell1Label.Text = batteryInfo.GetCell1(1); Battery2Cell1Label = batteryInfo.GetCell1(2). Battery2Cell1Label = batteryInfo.GetCell1(2)。

So in my base class I guess I need a GetValue(byte command) (since it is a Embedded controller command to get each different types of information.) Maybe i should stop talking and just post my code of what i have and tell you the error that I have. 因此,在我的基类中,我想我需要一个GetValue(byte命令)(因为它是一个嵌入式控制器命令,可以获取每种不同类型的信息。)也许我应该停止交谈,而只是发布我所拥有的代码并告诉您我有错误。

battery.cs battery.cs

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 Battery8800.cs

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 BatteryInformation.cs

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

YEAH FOR DRAFT SAVING!!! 是的,为了节省开支!!! the power just went out, and I didn't loose but 1 sentence! 力量刚刚消失,我没有松懈,只有一句话!

so while my computer was turning back on I was thinking it might be better to do something like this in my battery panel class. 因此,当我的计算机重新打开时,我想在电池面板课程中做这样的事情可能会更好。

    //in my timer_tick event
    BatteryInformation.UpdateBatteries();
    battery1Cell1Label.Text = BatteryInformation.Battery1.Cell1.ToString();
    //etc etc

but i still need to get this working but am having a hard time figuring out how to do abstraction. 但是我仍然需要使它正常工作,但是很难弄清楚如何进行抽象。 Thank you for your time. 感谢您的时间。

EDIT 编辑

I think i'm going about this the wrong way. 我想我要走错路了。

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

I have 9 files that are ALL identical in terms of how the Update command works the difference is in the enum. 我有9个文件,就更新命令的工作方式而言都是相同的,区别在于枚举。 The commands are slightly different per class. 每个类的命令略有不同。 look at batter2_8400.cs 's enum 看batter2_8400.cs的枚举

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

the update command is identical in that one as well as the other 7 files. update命令在一个和其他7个文件中是相同的。 Seems kinda bad design to me, but i'm stumped as to how I should do this. 对我来说似乎有点不好的设计,但我对如何执行此操作感到困惑。 By the way this is what my classes look like after the one answer I was given and the few comments that was received. 顺便说一句,这是我得到一个答案和收到一些评论之后我班级的样子。

your base class BatteryInformation should have abstract properties for each value you need to retrieve like so: 您的基类BatteryInformation应该为您需要检索的每个值都具有抽象属性,如下所示:

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
}

Then in your child class you implement each property 然后在子类中实现每个属性

public class Battery8800 : BatteryInfo {
    public override int VoltageHigh {
        get {
          int value;
          // do code to retrieve value
          return value;
        }
    }
}

In addition, I would provide a method somewhere that your UI can consume that looks like the following: 另外,我将在您的UI可以使用的某个地方提供一种方法,如下所示:

 public IEnumerable<BatteryInfo> GetAllBatteryInfo() {
   // get each battery
 }

That way the UI does not need to worry about how the battery info is retrieved for each battery. 这样,UI无需担心如何为每个电池获取电池信息。 That allows you to use one of the list or grid style controls to view the battery info. 这样您就可以使用列表或网格样式控件之一来查看电池信息。

In the end I think i figured out what I should do. 最后,我想我想出了该怎么做。 It looks clean to me and seems to make sense. 它对我来说看起来很干净,似乎很有意义。 Maybe you can critique it? 也许您可以批评它?

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

}

then on my sub classes that inherit it an example would be this 那么在继承它的子类上,一个例子就是

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

now all i have to do is edit the one file battery.cs if i need to make a change to it. 现在,我需要做的就是编辑一个文件battery.cs,如果我需要对其进行更改。

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

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