梓囚徒貧圭�鮗� ○ 賜 ★ 辛酔堀貧和鍬匈��梓囚徒貧議 Enter 囚辛指欺云慕朕村匈��梓囚徒貧圭�鮗� ● 辛指欺云匈競何��
!!!!隆堋響頼��紗秘慕禰厮宴和肝写偬堋響��
parameters�察�as follows�此�
Friend Class TaxEngine
Inherits BaseTaxEngine
Public Overrides Function CreateTaxAccount�┌� As ITaxAccount
Return New TaxAccount��Province。Ontario�察�2008��
End Function
End Class
In the implementation of CreateTaxAccount�┌��察�the province Ontario and year 2008 are
assumed。 Thus�察�whenever TaxEngine is instantiated�察�you need to make sure that the person is
in Ontario and paying taxes for the year 2008。 The implementation solves nothing and skirts
the issue of having to figure out how to deal with someone paying their taxes in British Columbia
and the year 2009。
If you look at the implementation of TaxEngine�察�you will notice it is short。 One obvious solu
tion would be to create a TaxEngine type for each province and each year。 Here are two examples�此�
´´´´´´´´´´´´´´´´´´´´´´Page 208´´´´´´´´´´´´´´´´´´´´´´´
186 CH AP T E R 7 * L E A R N IN G AB OU T CO M P O N E N TS AN D C L AS S H I E R AR C H IE S
Friend Class Ontario2008TaxEngine
Inherits BaseTaxEngine
Public Overrides Function CreateTaxAccount�┌� As ITaxAccount
Return New TaxAccount��Province。Ontario�察�2008��
End Function
End Class
Friend Class BritishColumbia2009TaxEngine
Inherits BaseTaxEngine
Public Overrides Function CreateTaxAccount�┌� As ITaxAccount
Return New TaxAccount��Province。BritishColumbia�察�2009��
End Function
End Class
This solution is not that bad�察�because to be able to instantiate the correct tax engine�察�you
just need to define a factory that knows which class to instantiate。 But for the problem at hand�察 �
this solution is extremely tedious�察�as you could end up with hundreds�察�if not thousands�察�of
TaxEngine definitions。 You would use the specific implementation approach when you have
fewer than a dozen variations。
The better approach is to add an interface specific to the Canadian tax system。 Think of it
as follows。 When you are instantiating the tax engine�察�you will need to know which tax system
to use。 The factory protects you from needing to know which type to instantiate�察�but there is
nothing wrong with giving some extra information that could be used by a factory。
Thus�察�the solution is to define a new interface called ICanadaTaxEngine。 The purpose of
ICanadaTaxEngine is to add factory methods that are used to instantiate types with parameters
specific to the implementation。 Following is the definition of the ICanadaTaxEngine。
Public Enum Province
Alberta
BritishColumbia
Manitoba
NewBrunswick
NewfoundlandLabrador
NovaScotia
Nunavut
Ontario
PrinceEdwardIsland
Quebec
Saskatchewan
Yukon
End Enum
Public Interface ICanadaTaxEngine
Function CreateTaxAccount��ByVal province As Province�察�_
ByVal year As Integer�� As ITaxAccount
Function CreateCapitalGain��ByVal amount As Double�� As ITaxIne
End Interface
´´´´´´´´´´´´´´´´´´´´´´Page 209´´´´´´´´´´´´´´´´´´´´´´´
CH AP T E R 7 * L E AR N IN G AB O U T CO M P O N E N TS AN D C L AS S H I E R AR C HI E S 187
The definition of ICanadaTaxEngine contains two additional methods�此�
o CreateTaxAccount�┌� is used to instantiate a tax account specific to a province and year。
o CreateCapitalGain�┌� is used to instantiate an ine using the Canadian capital gains
calculation。
Thus�察�the implementation of TaxEngine bees the following。
Friend Class TaxEngine
Inherits BaseTaxEngine
Implements ICanadaTaxEngine
Public Overrides Function CreateTaxAccount�┌� As ITaxAccount
Return New TaxAccount��Province。Ontario�察�2008��
End Function
Public Overloads Function CreateTaxAccount��ByVal province As Province�察�_
ByVal year As Integer�� _
As ITaxAccount _
Implements ICanadaTaxEngine。CreateTaxAccount
Return New TaxAccount��province�察�year��
End Function
Public Function CreateCapitalGain��ByVal amount As Double�� As ITaxIne _
Implements ICanadaTaxEngine。CreateCapitalGain
Return New TaxIne��amount�察�0。50��
End Function
End Class
In the modified implementation of TaxEngine�察�the class still derives from BaseTaxEngine�察 �
fulfilling the requirement of being a general tax engine。 However�察�for the additional require
ments of the Canadian tax system�察�we implement the ICanadaTaxEngine interface。
Defining a specific interface that implies a certain implementation is fine�察�because the
specific interface is not bound to a certain implementation。 The better way to understand
this implementation technique is to consider the specific interface as a characteristic that
an implementation is capable of supporting。 This goes back to the shape example�察�where a
square can support both the ISquare and IRectangle interfaces。
Using the Tax Engine
The last step is to use the tax engine to calculate some taxes。 The following is an example of
calculating the taxes for Ontario in 2008。
Dim engine As ITaxEngine = EngineCreator。CreateCanadianTaxEngine�┌�
Dim canadaEngine As ICanadaTaxEngine = TryCast��engine�察�ICanadaTaxEngine��
Dim account As ITaxAccount = canadaEngine。CreateTaxAccount��Province。Ontario�察�2008��
Dim ine As ITaxIne = engine。CreateIne��100��
Dim capitalGain As ITaxIne = canadaEngine。CreateCapitalGain��100��
´´´´´´´´´´´´´´´´´´´´´´Page 210´´´´´´´´´´´´´´´´´´´´´´´
188 CH AP T E R 7 * L E A R N IN G AB OU T CO M P O N E N TS AN D C L AS S H I E R AR C H IE S
account。AddIne��ine��
account。AddIne��capitalGain��
Dim deduction As ITaxDeduction = engine。CreateDeduction��20��
account。AddDeduction��deduction��
Dim taxToPay As Double = engine。CalculateTaxToPay��account��
Console。WriteLine�─�Tax to pay �──�& taxToPay & ;��;��
Notice the definition of the variables engine and canadaEngine。 This is fine�察�because what
we are doing with the interfaces is choosing a characteristic that can be dynamically queried。
Learning More About Inheritance and
Type Casting
This chapter introduced interfaces and ponents�察�and delved deeper into inheritance。 Here�察�I¨ll
provide more details about inheritance and type casting。
More Inheritance Details
In this section�察�I am going to clearly lay out how inheritance works in Visual Basic。 I will present
examples of usage for six scenarios。 Each example is followed by a list explaining the key points
to understand。 My goal is to illustrate all of the possible scenarios so that you have a reference
to how inheritance works。
*Note All of the examples demonstrate using methods�察�but it is possible to apply the same inheritance
techniques using properties。
Scenario 1�此�Overloading Base Class Functionality
Class Base
Public Sub Method�┌�
Console。WriteLine�─�Base。Method;��
End Sub
End Class
Class Derived
Inherits Base
Pu