嗔秤戻幣�哉膵�云利匈嬉蝕湊蛸賜�塋床四衲���萩晦編報炎嘔囚^泡仟 ̄云利匈��
VB2008貫秘壇欺娼宥(PDF鯉塀哂猟井)-及31何蛍
酔楯荷恬: 梓囚徒貧圭�鮗� ○ 賜 ★ 辛酔堀貧和鍬匈 梓囚徒貧議 Enter 囚辛指欺云慕朕村匈 梓囚徒貧圭�鮗� ● 辛指欺云匈競何! 泌惚云慕短嗤堋響頼���誅卒亮茂�俊彭堋響��辛聞喘貧圭 "辺茄欺厘議箝誓匂" 孔嬬 才 "紗秘慕禰" 孔嬬��
CH A PT E R 6 * L E A R N I N G T HE B AS IC S O F O B J E CT OR I E N TE D P R O G R AM M IN G 153
Public Class ActiveCurrencyTrader
Inherits CurrencyTrader
Private _fromCurrency As String
Private _toCurrency As String
Public Sub New��ByVal currExchange As Double�察�ByVal fromCurrency As String�察�
ByVal toCurrency As String��
ExchangeRate = currExchange
_fromCurrency = fromCurrency
_toCurrency = toCurrency
End Sub
End Class
The constructor has three parameters�此�currExchange represents the current exchange rate�察 �
fromCurrency indicates the source currency ��for example�察�USD���察�and toCurrency indicates the
destination currency ��for example�察�EUR��。 These three parameters are assigned to data members�察 �
whereby only the current exchange rate is assigned to the base class
CurrencyTrader。ExchangeRate。
Defining Informational Read´Only Properties
The characters that represent the from currency and to currency are stored as strings�察�and are
purely for informational purposes。 For example�察�let¨s say that you have instantiated a bunch of
currency pairs so that the trader can prehend the currency pair in which the values of
_fromCurrency and _toCurrency will be presented。 This means that the currency strings are
read´only properties and are coded as follows�此�
Public Class ActiveCurrencyTrader
Inherits CurrencyTrader
Private _fromCurrency As String
Private _toCurrency As String
Public Sub New ��ByVal currExchange As Double�察�
ByVal fromCurrency As String�察�ByVal toCurrency As String��
ExchangeRate = currExchange
_fromCurrency = fromCurrency
_toCurrency = toCurrency
End Sub
Public ReadOnly Property FromCurrency�┌� As String
Get
Return _fromCurrency
End Get
End Property
Public ReadOnly Property ToCurrency�┌� As String
Get
Return _toCurrency
End Get
End Property
End Class
´´´´´´´´´´´´´´´´´´´´´´Page 176´´´´´´´´´´´´´´´´´´´´´´´
154 CH AP T E R 6 * L E A R N IN G T HE B AS IC S O F OB J E CT OR I E N T E D P R O G R AM M IN G
The naming of the properties �─�FromCurrency and ToCurrency�� corresponds closely to the
naming of the data members ��_fromCurrency and _toCurrency��。 I do this throughout my code
so that I know what each piece of code means。 My convention is to use a leading underscore to
name private data members�察�but you can use a different notation if you prefer。
Adding the Conversion Methods
The last step to make the ActiveCurrencyTrader class plete is to add the functionality to
convert a value from or to a currency pair。 The ActiveCurrencyTrader class will use the exact
currency exchange rate。 The ConvertValue�┌��察�and ConvertValueInverse�┌� methods have protected
scope�察�and thus are not exposed outside the inheritance hierarchy。 ActiveCurrencyTrader
needs to define a pair of publicly scoped methods that will call the protected scope methods。
The following is the plete ActiveCurrencyTrader implementation。
Public Class ActiveCurrencyTrader
Inherits CurrencyTrader
Private _fromCurrency As String
Private _toCurrency As String
Public Sub New ��ByVal currExchange As Double�察�
ByVal fromCurrency As String�察�ByVal toCurrency As String��
ExchangeRate = currExchange
_fromCurrency = fromCurrency
_toCurrency = toCurrency
End Sub
Public ReadOnly Property FromCurrency�┌� As String
Get
Return _fromCurrency
End Get
End Property
Public ReadOnly Property ToCurrency�┌� As String
Get
Return _toCurrency
End Get
End Property
Public Function ConvertTo��ByVal value As Double�� As Double
Return ConvertValue��value��
End Function
Public Function ConvertFrom��ByVal value As Double�� As Double
Return ConvertValueInverse��value��
End Function
End Class
The ConvertTo�┌� and ConvertFrom�┌� methods are wrappers to the ConvertValue�┌� and
ConvertValueInverse�┌� methods�察�and provide no added value。 But remember the problem of
the cashier and credit card。 Just because it seems like there is no added value�察�the reality is that
you are writing code that is acting as a gatekeeper and giving yourself flexibility。
´´´´´´´´´´´´´´´´´´´´´´Page 177´´´´´´´´´´´´´´´´´´´´´´´
CH A PT E R 6 * L E A R N I N G T HE B AS IC S O F O B J E CT OR I E N TE D P R O G R AM M IN G 155
For example�察�suppose that CurrencyTrader。ConvertValue�┌��察�and CurrencyTrader。
ConvertValueInverse�┌� were declared using Public rather than Protected。 Then any user of
ActiveCurrencyTrader could use the functionality exposed by CurrencyTrader。 Suppose someone
decided to change the functionality of ConvertValue�┌� and ConvertValueInverse�┌�。 At that
point�察�you would have problems�察�because the changes to CurrencyTrader automatically imply
changes in ActiveCurrencyTrader。 By defining your own methods�察�you are controlling and
making sure that if things change in the future�察�you can acmodate them without needing
to change the callers of ActiveCurrencyTrader。
We have now pleted the functionality of ActiveCurrencyTrader�察�so let¨s implement
HotelCurrencyTrader。
Implementing HotelCurrencyTrader
The difference in features between HotelCurrencyTrader and ActiveCurrencyTrader is the
existence of a sizable spread。
Adding a Constructor to HotelCurrencyTrader
Again�察�we¨ll begin by adding a constructor。 The HotelCurrencyTrader constructor needs an
additional parameter value referencing a spread。 Following is the code for the
HotelCurrencyTrader class�察�including its constructor。
Public Class HotelCurrencyTrader
Inherits CurrencyTrader
Private _fromCurrency As String
Private _toCurrency As String
Private _spread As Double
Public Sub New ��ByVal currExchange As Double�察�ByVal spread As Double�察�
ByVal fromCurrency As String�察�ByVal toCurrency As String��
ExchangeRate = currExchange
_fromCurrency = fromCurrency
_toCurrency = toCurrency
_spread = spread
End Sub
Public ReadOnly Property FromCurrency�┌� As String
Get
Return _fromCurrency
End Get
End Property
Public ReadOnly Property ToCurrency�┌� As String
Get
Return _toCurrency
End Get
End Property
End Class
´´´´´´´´´´´´´´´´´´´´´´Page 178´´´´´´´´´´´´´´´´´´´´´´´
156 CH AP T E R 6 * L E A R N IN G T HE B AS IC S O F OB J E CT OR I E N T E D P R O G R AM M IN G
In the constructor of HotelCurrencyTrader�察�you can see the additional parameter spread。
The spread parameter is assigned to the data member _spread and represents a calculation
that modifies the exchange rate。
Adding the Conversion Methods to HotelCurrencyTrader
Remember in the previous section how the methods ConvertTo�┌� and ConvertFrom�┌� seemed
to add no extra value。 For HotelCurrencyTrader�察�they will add value and illustrate why it is useful
to create indirect exposure。 Calculating what people will receive for their currency depends on
the exchange rate�察�and in the case of the hotel�察�the exchange rate has a spread。 As explained
earlier in this chapter�察�this means you will never get as much as you hoped and will always pay
more than you expected。
The following is the source code for the HotelCurrencyTrader implementations of
ConvertTo�┌� and ConvertFrom�┌�。
Public Class HotelCurrencyTrader
Inherits CurrencyTrader
Private _fromCurrency As String
Private _toCurrency As String
Private _spread As Double
Public Sub New ��ByVal currExchange As Double�察�ByVal spread As Double�察�
ByVal fromCurrency As String�察�ByVal toCurrency As String��
ExchangeRate = currExchange
_fromCurrency = fromCurrency
_toCurrency = toCurrency
_spread = spread
End Sub
Public ReadOnly Property FromCurrency�┌� As String
Get
Return _fromCurrency
End Get
End Property
Public ReadOnly Property ToCurrency�┌� As String
Get
Return _toCurrency
End Get
End Property
Public Function ConvertTo��ByVal value As Double�� As Double
Dim realExchange As Double = ExchangeRate
ExchangeRate = realExchange _spread
Dim retval As Double = ConvertValue��value��
ExchangeRate = realExchange
Return retval
End Function
´´´´´´´´´´´´´´´´´´´´´´Page 179´´´´´´´´´´´´´´´´´´´´´´´
CH A PT E R 6 * L E A R N I N G T HE B AS IC S O F O B J E CT OR I E N TE D P R O G R AM M IN G 157
Public Function ConvertFrom��ByVal value As Double�� As Double
Dim realExchange As Double = ExchangeRate
ExchangeRate = realExchange �� _spread
Dim retval As Double = ConvertValueInverse��value��
ExchangeRate = realExchange
Return retval
End Function
End Class
The ConvertTo�┌� and ConvertFrom�┌� methods have the added logic in that the spread will
be added or subtracted from the exchange rate。 The methods read the current exchange rate�察 �
assign it to a temporary variable�察�define a new exchange rate taking into account the spread�察 �
calculate the currency�察�and then reassign the exchange rate。
The ConvertTo�┌� and ConvertFrom�┌� methods swap values to achieve the desired calcula
tions。 There is absolutely nothing wrong with doing this�察�and you will often swap values in your
own code。 What is important is to restrict access on what classes can do this。 Because ExchangeRate
is a property with protected access�察�it means only those classes that subclass can assign and
change the value of ExchangeRate。 And this implies that the class doing the subclassing knows
what it is doing to the data。 It is a valid assumption and one that you can use to your benefit。
The caller is not aware of this swapping�察�because HotelCurrencyTrader is taking advantage of
the object´oriented technique to not expose the state of the type。
That¨s it!we¨re finished with the currency exchange application。 For the remainder of
this chapter�察�I will fill in some extra details that are important。
Learning More About Preprocessor Directives�察 �
Properties�察�and the MustOverride Keyword
Some details about preprocessor directives�察�properties�察�and the MustOverride keyword that did
not e up in this chapter¨s example are worth mentioning。 These are things you should
know about when writing your own code。
More Preprocessor Directive Details
Earlier in the chapter�察�you saw how you can use the hash character ��#�� and conditional state
ments to conditionally include code during pilation。 The technical term for this jargon is
called preprocessing the code�察�and the statements are called preprocessor directives。 Table 6´1
shows the preprocessor directives you can use。
Table 6´1。 Available Preprocessor Directives
Hash Code Description
#Const Used to define the pilation identifier�察�such as the INTEGRATE_TESTS
identifier used in this chapter¨s example。 You would define this at the top
of a source code file to activate conditional preprocessor statements
used throughout the source code file。 Using a #Const directive does not
span multiple source code files。
#If and #End If Used to conditionally include or not include a piece of source code。 You
would use a conditional directive whenever you wanted to define source
code configurations�察�such as for debug or production builds。
´´´´´´´´´´´´´´´´´´´´´´Page 180´´´´´´´´´´´´´´´´´´´´´´´
158 CH AP T E R 6 * L E A R N IN G T HE B AS IC S O F OB J E CT OR I E N T E D P R O G R AM M IN G
Table 6´1。 Available Preprocessor Directives ��Continued��
Hash Code Description
#ElseIf Instead of a single #If block�察�you could have multiple tests for code
inclusion。 You would use #ElseIf when you have more than a single
preprocessor directive�察�such as for debug�察�production�察�and performance
builds。
#Else A default code block that is included if the other #If statements did
not trigger。
#Region and These have absolutely nothing to do with the pilation of the source
#EndRegion code。 They are used by Visual Studio to create regions of source code that
can be ^folded。 ̄ Folding means to collapse a block code out of sight
temporarily。 Source code files can be bee long�察�and constantly paging
up and down bees tedious。 By folding the code�察�you are reducing the
amount of times that you need to page up and down�察�even though the
code still exists。
The following example demonstrates how to use the preprocessor directives。
#Const ACTIVATE_1 = True
Namespace TestDefine
Class Example
酔楯荷恬: 梓囚徒貧圭�鮗� ○ 賜 ★ 辛酔堀貧和鍬匈 梓囚徒貧議 Enter 囚辛指欺云慕朕村匈 梓囚徒貧圭�鮗� ● 辛指欺云匈競何!
梁椣戻幣�� 梁心弌傍議揖扮窟燕得胎��傍竃徭失議心隈才凪万弌誌育断蛍�輌臆惨軼僑〃�燕慕得珊辛參資誼持蛍才将刮襲潜��範寔亟圻幹慕得 瓜寡追葎娼得辛參資誼寄楚署衛、持蛍才将刮襲潜填��