Rom*_*EE2 5 containers vba class object
对于我来说,这是一个关于学习面向对象方法的问题,因为它与VBA语法有关.假设我创建了几个类,如Car,Truck,Bus等.我创建了另一个类SpeedCalculator,我的车辆实例将实例化并包含.(作为一个新手,让我注意到这是一个很好的时间来宣布一个类是静态的而不是实例化它 - 哪个vba不能做我不认为.......)现在这个速度计算器将是没有简单的车速表.相反,它将根据温度,风速,RPM等计算速度 - 请与此一起,仅为了示例.
现在问题是所包含的对象如何收集其输入,这些输入仅在容器对象中可用(车辆对象可能实现接口(如果VBA甚至可以这样做......))."家长".是错的,我最终想通了,b/c parent-child是一个继承关系(VBA没有,再次),不是包含关系,包含对象的父是Excel应用程序(不是我的对象) .因此,如果有另一个关键字来引用容器属性,那似乎会很好.我希望我不会错过一些简单的事情.或者更多的情况是,这种引用会破坏面向对象的封装原则?
我想第二种方法是将容器传递给包含的,通过"Me"作为参数.但是你必须将所有包含的方法相乘,要么重载它们(如果VBA甚至可以这样做......),要么使用不同命名的版本 - 由于容器的类型不同(我们可以更理想化和避免声明为变体或"对象"?).
然后门#3将是最后一扇门,我猜?这将是一个(恼人的)一连串的争论.所有这些的定义往往会破坏我整洁的小计算器类的目的?
我不清楚你的问题是否已经知道VBA和/或OO,并且只是询问如何使用VBA的面向对象功能.如果您不熟悉VBA和OO,请参阅下文,了解为什么VBA不是学习OOD/OOP的好工具.
为了解决问题的一般部分,VBA类可以实现接口.这是在VBA中表达接口继承("is-a"关系)的方式.没有直接的方法来表达VBA中的实现继承.相反,要使一个类继承另一个类的实现,您首先实现第二个类的接口,包含第二个的实例,然后委托对该实例的调用.请参阅此答案了解更多信息
这里有一个链接,我将在这里重复一遍Visual Studio 6.0程序员指南:
http://msdn.microsoft.com/en-us/library/aa240846(v=VS.60).aspx
它与OOP的"VBA方式"中的任何简短介绍一样好(尽管它是为VB6编写的,而不是VBA).
现在,针对您关于设计的具体问题:"所包含的对象如何收集其输入,这些输入仅在容器对象中可用".
你需要考虑一下你在这里建模的内容.无论你如何实现它,"速度计算器"应该只了解一组非常具体的输入,而不是任何车辆使用它的整个内部状态.在VBA中,正如您所注意到的,没有静态类.相反,使用常规代码模块并具有从车辆类内部调用的功能:
Public Function calcSpeed(temp, windspeed, rpm)
'do calc based only on parms passed in...
End Function
Run Code Online (Sandbox Code Playgroud)
如果它需要采用多个参数,因为这是计算的工作方式,那就这样吧.不要试图隐藏它.当然,Type如果有太多,你可以将它们包装在一个或一个类中.
现在,每种不同类型的车辆是否以完全相同的方式从完全相同的状态参数集计算速度?如果是这样,那么拥有一个speed由你的"基础车辆"类实现的属性或方法,并calcSpeed从那里打电话.
但也许情况是不同类型的车辆具有不同的状态参数,或者使用不同的计算方法,或者计算是相同的但不是每个车辆类型都提供每个参数.在这种情况下,将speed方法放在基础车辆界面中,但在每个子类的实现中根据需要"覆盖"它.(也许那时calcSpeed太简单了,你最终得到了一个速度计算辅助函数库.)
我不会做的一件事是,有一个通用的SpeedCalculator类,它接受一个Vehicle参数,然后询问它的状态,以便进行计算.之所以没有在这些经典文章中表达得非常好:
http://media.pragprog.com/articles/may_04_oo1.pdf
http://pragprog.com/articles/tell-dont-ask
http://www.cmcrossroads.com/bradapp/docs/demeter-intro.html
还有这个:
http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/paper-boy/demeter.pdf
哪个引用我喜欢:
那么,这段代码有什么不好(除了是一个可怕的人为例子)?好吧,让我们将代码实际执行的内容翻译成实际语言:
显然,当报童停下来并要求付款时,顾客只是转身,让报童从后口袋里取出钱包,拿出两块钱.
我不了解你,但我很少让别人处理我的钱包.这有一些"真实世界"的问题,更不用说我们相信纸质经纪人是诚实的,只是拿出他所欠的东西.如果我们未来的电子钱包对象持有信用卡,那么报童也可以访问这些信息卡......但基本问题是"报童正在接触到比他需要的信息更多的信息".
这是一个重要的概念......'Paperboy'课程现在'知道'客户有钱包,并且可以操纵它.当我们编译Paperboy类时,它将需要Customer类和Wallet类.这三个类现在"紧密耦合".如果我们更改Wallet类,我们可能必须对其他两个类进行更改.
在评论中添加:
并不是说你不能轻易拥有Speedometer你的Vehicles中包含的类的实例.(我的一个简单函数的例子可能过于简单.也许你需要一个类来模拟速度表的其他东西 - 它们有质量,占用空间等等.)这两个类是如何相互依赖的.在这个例子中,Vehicle需要了解Speedometer.但为什么反过来应该如此呢?如果Speedometer将a Vehicle作为参数,然后询问它需要知道的特定事物来计算速度,那么代码肯定会起作用.但是,你再加Speedometer以Vehicle更紧密地比必要的.
首先使用面向对象方法的原因之一是因为它可以让您更准确地了解概念如何相互关联.最好Vehicle告诉他们Speedometer,"这里有一些关于这个世界的事实.给我一个速度."而不是"我在这里Me,Vehicle那就是你的意思.请问我对你有什么需要和我有什么关系,以及然后给我一个速度." (请注意,"关于世界的事实"是原始温度,风速等,还是某种SpeedometerInput类型/类别的实例不是问题.速度表不需要了解所有车辆.)
在一个简单的例子中,使用最精确的界面你可以逃脱并不是那么大的交易.但是,当在许多设计决策中加起来时,它变得巨大.
最后,如果您有选择,我不会将VBA用作学习面向对象设计或编程的工具.您可以在VBA中执行"OOP",但是以Microsoft/COM特定的方式执行,这实际上是20世纪90年代中期的遗留物.您可以浏览stackoverflow以获取大量通常在OO编程语言(以及更好的库)中完成的事情示例,这些事件在VBA中很麻烦且棘手.我要么回答了以下几个问题:
有没有办法为私有成员编写VBA类的相等测试而不暴露这些私有成员存在的知识?
Excel-VBA - VBA中有Javas Set容器吗?
所以,除非你被限制学习VBA,因为你不能在你的机器上安装除了MS Office以外的任何东西,或者你打算做很多VBA工作,因为你正在使用 Excel,Access等等. OOP可以提供帮助的一些问题,我会去别处看看.Python,.NET或Java都可以在Windows上免费获得,并且为初学者提供了大量资源.
| 归档时间: |
|
| 查看次数: |
4382 次 |
| 最近记录: |