Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Class 直接使用私有属性与使用Get和Let/Set_Class_Vba_Oop_Properties_Private - Fatal编程技术网

Class 直接使用私有属性与使用Get和Let/Set

Class 直接使用私有属性与使用Get和Let/Set,class,vba,oop,properties,private,Class,Vba,Oop,Properties,Private,初学者VBA程序员在这里(和初学者编程一般),希望了解更多关于如何有效的OOP是做 是否有人可以解释或提供一个参考,讨论在类模块内部使用私有属性Get和/或Let/Set语句相对于直接访问属性的好处/目的,尽管不需要对数据进行操作 例如: 我已经创建了一个cDimension类(在Excel中)。此类将线条绘制为形状对象,以及其他一些不相关的内容。DrawingScale变量允许根据需要缩放整个图形。某些属性在获取/设置时需要操纵,而其他属性则不需要操纵 因此,例如,pWidth需要按比例放大:

初学者VBA程序员在这里(和初学者编程一般),希望了解更多关于如何有效的OOP是做

是否有人可以解释或提供一个参考,讨论在类模块内部使用私有属性Get和/或
Let
/
Set
语句相对于直接访问属性的好处/目的,尽管不需要对数据进行操作

例如:

我已经创建了一个
cDimension
类(在Excel中)。此类将线条绘制为
形状
对象,以及其他一些不相关的内容。
DrawingScale
变量允许根据需要缩放整个图形。某些属性在获取/设置时需要操纵,而其他属性则不需要操纵

因此,例如,
pWidth
需要按比例放大:

'clsDimension
Private pWidth As Single    
Private Property Get Width() As Single
    Width = pWidth
End Property
Private Property Let Width(w As Single)
    pWidth = w / DrawingScale
End Property
但是,
pColor
不需要任何操作,输入或输出:

Private pColor As Integer
Private Property Get Color() As Integer
    Color = pColor
End Property
Private Property Let Color(c As Integer)
    pColor = c
End Property
pWidth属性是一个实例,在这个实例中,对于类本身内部的过程,使用私有属性Get和Let方法是有意义的。但是,我的问题是:是否有任何理由也使用私有属性方法来获取和让/设置pColor属性,正如我在上面给出的那样

Public Function Line(sht As Worksheet, L As tLine, Optional c = vbBlack) As Shape
    Width = DistanceBetweenTwoPoints(L.first.x, L.first.y, _
                                     L.second.x, L.second.y) '<-- pWidth is scaled
    Color = c '<-- Vs. just using pColor = c
    Set Line = sht.Shapes.AddLine(L.first.x, L.first.y, L.second.x, L.second.y)
End Function
公共功能线(sht作为工作表,L作为T线,可选c=vbBlack)作为形状
宽度=两点之间的距离(L.first.x,L.first.y_

L.second.x,L.second.y)“如果您没有在输入或输出的过程中操作值,只需使用公共变量即可。VBA更像Python而不是java或C++,在<强>中没有真正的惩罚,从公共变量切换到“吸气剂/ SETER”功能,沿路< /St>>/P> 假设您从以下代码开始:

'clsCar
Public Speed As Double
Public Sub Drive()
    MsgBox "Driving at " & Speed & " MPH"
End Sub    


'Module1
Sub DriveCar()
    Set Car = New clsCar
    Car.Speed = 100
    Car.Drive  'shows msg:  "Driving at 100 MPH"
End Sub
然后你决定开那么快的车是危险的,所以你想给你的车添加一个“调速器”,并需要更新你的等级:

'clsCar
Private mSpeed As Double
Private Const SpeedLimit As Double = 55

Public Property Get Speed()
    Speed = mSpeed
End Property
Public Property Let Speed(Val As Double)
    If Val > SpeedLimit Then
        mSpeed = SpeedLimit
    ElseIf Val < 0 Then
        mSpeed = 0
    Else
        mSpeed = Val
    End If
End Property
Public Sub Drive()
    MsgBox "Driving at " & Speed & " MPH"
End Sub    


'Module1
'Note that no changes to this code are necessary; the change
'   is entirely encapsulated within the class (as it should be)
Sub DriveCar()
    Set Car = New clsCar
    Car.Speed = 100
    Car.Drive  'shows msg:  "Driving at 55 MPH"
End Sub
'clsCar
私人mSpeed为双倍
私人康斯特速度限制为双倍=55
公共财产获得速度()
速度=毫秒速度
端属性
公共财产出租速度(Val为双倍)
如果Val>SpeedLimit,则
mSpeed=速度限制
ElseIf Val<0则
mSpeed=0
其他的
mSpeed=Val
如果结束
端属性
公共子驱动器()
MsgBox“以”速度和“英里/小时”驾驶
端接头
'模块1
“请注意,无需对该代码进行任何更改;变化
'完全封装在类中(应该是这样的)
副驱动车()
设置车辆=新的clsCar
汽车。速度=100
Car.Drive'显示消息:“以55英里/小时的速度驾驶”
端接头

Tim Williams的评论通常被认为是在VBA中不必要地使用Get/Let/Set的理由,但这是其他语言(特别是C++和Java)的好建议被误用到VBA/VB6的副产品。

一如既往。。。。视情况而定。您的x属性肯定应该通过字母访问,因为字母对输入执行计算

'clsDimension
Private Let Width(w As Single)
    pWidth = w / DrawingScale
End Property
您不应该直接访问
pWidth
变量。如果您这样做了,您将不得不在模块的其他地方复制
pWidth=w/DrawingScale
逻辑


您的
pColor
属性可能是一个公共变量,因为获取或设置它时没有逻辑。不过我不推荐。如果以后你意识到你不想允许某些颜色怎么办?然后,您需要它背后的逻辑,并且无论如何都需要切换到属性。属性更易于维护,语义更正确。

我看到的值是简化代码,您在示例代码中没有利用它。您可以替换此:

'clsDimension
Private pWidth As Single    
Private Property Get Width() As Single
    Width = pWidth
End Property
Private Property Let Width(w As Single)
    pWidth = w / DrawingScale
End Property
为此:

'clsDimension
Private Property Get Width() As Single
    Width = w / DrawingScale
End Property

这消除了访问pWidth或width属性的潜在模糊性,因为pWidth不再存在。它还消除了在写入之前读取宽度的潜在陷阱,尽管在读取宽度之前添加一点代码检查w和DrawingScale是否已设置为有效值是明智的。

代码维护和演化意味着“不需要任何操纵”并不总是以“永远不需要…”,所以“永远“使用属性Let/Get,即使是在类中,也不要直接使用私有支持字段。答案很简单,但我想这是有意义的。谢谢我曾经和一个人合作过,他将他们所有的类模块变量都声明为公共的而不是私有的,这样他们就可以在没有get和let的情况下使用,这对我来说总是很奇怪。我通常认为类模块执行某些操作,而不仅仅是用作数据类型,因此我通常使用get和let,并对任何输入的内容执行一些数据验证,以限制和控制类中显示的内容。如果你问我的话,这是一个优势,但我不确定你在那里的编码范例中会如何描述它。你的语法实际上不太正确,你可能想编辑它以包含属性关键字。编写的代码将无法编译。谢谢。据此编辑。