我正在编写一些软件,可以自动从实验中收集数据,并需要一些帮助来表达我的业务对象之间的关系。
我有一个名为Experiment
的类型,一个名为Sample
的类型,以及RunOnSample
中未实现的Experiment
方法,它应该接受Sample
的派生输入数据并填入其中:
Public MustInherit Class Experiment
Public Property TestDate As Date
Public Property Experimenter As String
Public MustOverride Sub RunOnSample(sample As Sample)
End Class
Public MustInherit Class Sample
Public Property UnitLotCode As String
End Class
这些类型都不是实际可实例化的,因为我有不同的实验(由Experiment
的子类型表示),它们生成各种数据。每个实验都有一个匹配的Sample
子类型,该子类型具有存储实验生成的数据的属性。请注意,基类是必要的,因为所有实验都有一些共同的属性,以及将为所有样本记录的一些数据。
例如,ThicknessExperiment
测量厚度数据并扫描大量代码,然后将此数据填入ThicknessSample
:
Public Class ThicknessExperiment
Public Overrides Sub RunOnSample(sample As ThicknessSample)
Dim data = GetDataFromMeasurementDevice()
sample.UnitLotCode = data.LotCode
sample.Thickness = data.Thickness
End Sub
End Class
Public MustInherit Class ThicknessSample
Public Property Thickness As Single
End Class
这里的问题是参数的类型对编译器是不可接受的; RunOnSample
的实施必须接受Sample
,而不是ThicknessSample
(或Sample
的任何其他子类型)。大概这是因为,如果编译器让我按照自己的方式进行,派生的实验将不再具有与父类相同的接口,这将是非多态的。
我能想到解决这个问题的唯一方法是在使用之前将参数转换为方法内的Sample
的相应子类型。有没有更好的方法来实现我的目标?最好是一种维护XYZExperiment.RunOnSample
方法与XYZSample
参数的强类型关联的方法吗?
答案 0 :(得分:1)
首先,我想说,作为一个个人偏好和一点经验我学会了不使用继承代码重用或公共属性,但是只是为了从多态中受益,所以我将这些公共数据属性提取到一个新类中,并使用字典表示不同的属性,然后使用委托(组合)来存储某个样本的数据。无论如何,我建议的解决方案涉及使用泛型,所以你可以做这样的事情:
public abstract class Experiment<TSample>
where TSample : Sample
{
private DateTime experimentDate;
private string Experimenter;
public abstract void RunOnSample(TSample sample);
}
public class ThicknessExperiment : Experiment<ThicknessSample>
{
public override void RunOnSample(ThicknessSample sample)
{
// sample.lotcode = "43";
// sample.data1 = "343";
// sample.data2 = "43";
}
}
public abstract class Sample
{
public string lotcode;
}
public class ThicknessSample : Sample
{
public string data1;
public string data2;
}