按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
diameter; a triangle has base width; height; and triangle peak offset。 The point is that the idea
of a shape is not the idea of a rectangle or a square。
The correct way to define the ideas as interfaces would be as follows:
Interface IShape
Function CalculateArea() As Double
End Interface
Interface ISquare
Inherits IShape
Property Width() As Double
End Interface
Interface IRectangle
Inherits IShape
Property Width() As Double
Property Length() As Double
End Interface
This code contains three interfaces: IShape; which defines a shape; IRectangle; which
describes a rectangle; and ISquare; which describes a square。 The IRectangle and ISquare
interfaces subclass the IShape interface; indicating that an IRectangle is also an IShape。 The
ISquare interface is separate from the IRectangle interface; because the idea of a square (four
equal sides) is not the same as the idea of a rectangle (only the parallel sides of the four sides
must be equal); even though the shapes might appear similar (in real life; a square is a rectangle;
but a rectangle is not necessarily a square)。
This separation of the square and rectangle interface illustrates that when designing inter
faces; you need to focus on the specific behavior of the interface。 You don’t want to focus on
…………………………………………………………Page 194……………………………………………………………
172 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
the general behavior。 The general behavior is managed when you design the classes。 The modeling
of your real…life experiences is defined in the implementations; as illustrated by the following
example。
Class SquareImpl
Implements ISquare; IRectangle
End Class
Class RectangleImpl
Implements IRectangle
End Class
The SquareImpl class implements the behavior of ISquare and IRectangle; and models real life;
where a square is also a rectangle。 And RectangleImpl implements only the behavior IRectangle;
illustrating that a rectangle can only be a rectangle and not a square。 Now you cannot write
code where the implementation produces inconsistent results。
■Note When defining ideas; the resulting interfaces could be considered as behavior characteristics that
an implementation can have。 It is entirely possible for an implementation to have multiple behavior character
istics。 For example; this could mean that an implementation could be both a square and rectangle at the same
time。 In terms of the restaurant; waiters are humans with hobbies; feelings; and desires; although you don’t
know these other aspects; as you see only the waiters。
An optimization could have been the following interface inheritance。
Interface ISquare
Inherits IShape
Property Width() As Double
End Interface
Interface IRectangle
Inherits ISquare
Property Length() As Double
End Interface
or
Interface ISquare
Inherits IRectangle
End Interface
Interface IRectangle
Inherits IShape
Property Width() As Double
Property Length() As Double
End Interface
…………………………………………………………Page 195……………………………………………………………
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 173
However; this isn’t a good idea; because at the interface level; you are implying that a square
and rectangle are related。 They might be at the implementation level; but they also might not
be。 For example; imagine you are creating a super shape that has the characteristics of a rect
angle and a triangle。 When creating a relationship between interfaces; you are implying that
the super shape depending on the interface inheritance used must have the characteristics of
a square; even though it might not。 Thus; when using inheritance with interfaces; IShape as a
base interface of IRectangle and ISquare is acceptable; but a relation between IRectangle and
ISquare is not。
Now that you have an idea of the differences between inheritance and ponents; we
can get started with our tax application。 As we work through the example; you’ll learn the
details of implementing interfaces。
Implementing a Tax Engine
So far; we’ve discussed some basic tax concepts; the features of the tax application; and the
theory of inheritance; interfaces; and ponents。 We’re ready to implement the tax engine。
The preferred approach is to design the core idea and then create the other pieces; or
dependencies。
Defining the Interfaces
Putting everything together and starting with the tax engine; we can create the following
interface structure。
Public Interface ITaxIne
ReadOnly Property RealAmount() As Double
ReadOnly Property TaxableAmount() As Double
End Interface
Public Interface ITaxDeduction
ReadOnly Property Amount() As Double
End Interface
Public Interface ITaxAccount
Sub AddDeduction(ByVal deduction As ITaxDeduction)
Sub AddIne(ByVal ine As ITaxIne)
Function GetTaxRate(ByVal ine As Double) As Double
ReadOnly Property Deductions() As ITaxDeduction()
ReadOnly Property Ine() As ITaxIne()
End Interface
Public Interface ITaxEngine
Function CalculateTaxToPay(ByVal account As ITaxAccount) As Double
Function CreateDeduction(ByVal amount As Double) As ITaxDeduction
Function CreateIne(ByVal amount As Double) As ITaxIne
Function CreateTaxAccount() As ITaxAccount
End Interface
…………………………………………………………Page 196……………………………………………………………
174 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
We have four interfaces here: ITaxIne; ITaxDeduction; ITaxAccount; and ITaxEngine。
ITaxIne and ITaxDeduction are pure behavioral interfaces。 Pure behavioral means the inter
face does one thing; but it might be implemented in conjunction with other interfaces。 ITaxEngine
and ITaxAccount are behavioral functional interfaces。 Behavioral functional means that the
interfaces are typically implemented by themselves; and usually not with another interface。
For example; you might implement a Swiss tax system where there are two classes; defined
as follows:
Class SwissTaxEngine
Implements ITaxEngine
End Class
Class SwissTaxAccount
Implements ITaxAccount
End Class
And if you wish to implement an American tax system; the two classes would be defined
as follows:
Class AmericanTaxEngine
Implements ITaxEngine
End Class
Class AmericanTaxAccount
Implements ITaxAccount
End Class
The user of either the American or Swiss tax system will not know the specific details of
those tax systems。 Initially; users would need to determine which tax system they wished to
use。 This decision is made using something called a factory; as explained in the uping
“Abstracting Instantiations with Factories” section。
Implementing a Base Class Tax Engine
Whenever you define interfaces; you will need to implement them。 In most cases; you will
create a MustInher