按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
able names used instead of the identifiers for the currency variables:
Dim cls As CurrencyTrader = New CurrencyTrader()
cls。ExchangeRate = 1。46
Dim ukfkisd As Double = 100。0
Dim didkfdbnfd As Double = cls。Convert(ukfkisd)
Console。WriteLine(〃Converted 〃 & ukfkisd & 〃 USD to 〃 & didkfdbnfd)
This code is structural; rather than architectural。 Structural code is code that requires an
intelligent programmer—a programmer who knows what the individual items mean。 In this
case; the programmer must know that the Convert() method converts from USD to EUR and
therefore needs to supply the correct values at the correct time。
Architectural code; on the other hand; is more idiot…proof and requires less knowledge;
because many parts are encapsulated。 The user needs to understand only how to use the classes。
Put another way; structural code is knowing how to add two numbers。 Architectural code
is knowing how to punch in the two numbers and hit the plus sign on a calculator。 You can
argue that by not knowing how to add and relying on the calculator; you have no idea if the
calculator is doing its job properly。 That is a valid point; and that is why tests are important to
ensure that the calculator is doing its job properly。
Understanding Base Classes
The first test code; which is structural; is not wrong。 Structural code forms the basis of what is
called a base class。 A base class is a class that provides certain functionality that will be reused
by other classes。 In this case; converting the currency units is functionality that we will need
in both the active trader and hotel trader。 You define base classes so that you get consistent
behavior when performing identical operations。 In lieu of base classes; you would need to copy
and paste the functionality to reuse it。
Base classes have some very important characteristics:
…………………………………………………………Page 161……………………………………………………………
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 139
o Only developers who understand what the base class code is trying to do should use the
base class code。 In other words; only those with expert domain knowledge should touch
the internals of the base class。 To control access; we will use scope。
o Base classes describe properties and methods that are mon across multiple
applications。
o Base classes need extensive testing because their functionality will be used throughout your
code。 If the base classes have bugs; most likely a large chunk of your code will have bugs。
■Note Base classes are a general concept that only developers understand fully。 A general concept is called
a design pattern。 Design patterns create a developer lingo where words like factory; state; and visitor refer to
specific coding concepts that developers understand without needing to explain the coding concept。 I suggest
that you learn more about design patterns。 The Data & Object Factory web site (http://dofactory。/
Patterns/Patterns。aspx) has some excellent coding examples of essential patterns used by developers。
In the current example; the CurrencyTrader class needs to be converted into a base class
that can be used only by knowledgeable developers (those who know about currency trading)。
You want to prevent your source code from being used in the wrong context。
One way to stop usage in the wrong context is to declare the CurrencyTrader class as
MustInherit。 The MustInherit keyword says that the class in question cannot be instantiated。
You can reference the class; but you cannot instantiate the class。 Consider the following code;
which declares CurrencyTrader as MustInherit。
MustInherit Class CurrencyTrader
End Class
Using MustInherit implies that someone needs to create a class that can be instantiated;
using a mechanism called inheritance。 Note that any class can be extended in this way; but
MustInherit marks a class that is specifically designed to be extended。 From a developer
perspective; the idea behind MustInherit is to embed reusable logic used by some other class。
Using MustInherit implies inheritance。
Understanding Inheritance
Inheritance is similar to a genealogy tree; in that you have a tree structure where there is a parent;
and the descendants of the parent are children。 And like the genealogy tree; the structure can
have multiple levels。 However; inheritance is not quite like genealogy; because genealogy requires
a pair of humans to create a tree。
A class uses inheritance to gain functionality from the base class and bees a subclass
of that base class。 Inheritance; and in particular ; has a tree structure where there is only a
single root parent。 When you use inheritance; you can gain functionality; but you can also override
functionality; as illustrated in Figure 6…1。
…………………………………………………………Page 162……………………………………………………………
140 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
Figure 6…1。 Simple two…level inheritance example using the awesome BMW 530i and 530xi
The pictures in Figure 6…1 seem to illustrate the same car; but in fact; they are two different
models with a major difference in their power trains。 From an inheritance perspective; the
BMW 530i could be considered the parent of the BMW 530xi。
■Note The order of which is the parent and which is the child is my logic; some might disagree。 This
disagreement is healthy and part of the object…oriented design process。
The first model that you would design would probably be the rear…wheel…drive model;
since it is simpler to design; cheaper; and more popular。 You would consider all…wheel drive as
a feature。 The all…wheel…drive model is not a pletely new car。 Both the 530i and 530xi would
share the same tires; motor; steering wheel; body trim; and so on。 What would be different is
that the 530xi replaces the power train; thus changing the behavior of the car。
Let’s say that you are a driver sitting in the seat driving your BMW; and it’s a snowy night
in Canada。 Whether you are driving the 530i or the 530xi; you would use the same steering
wheel; blinkers; gas pedal; brake; and so on。 But the behavior of the 530i and 530xi would be
different—the rear…wheel…drive car might slide around a bit more than the all…wheel…drive car。
The power train overrides behavior; which means the consumer of the hierarchy sees the same
interface (for example; methods and properties); but gets different behavior。
Another way to use inheritance is not to replace functionality; but to enhance function
ality; as illustrated in Figure 6…2。 This is called overloading behavior。
…………………………………………………………Page 163……………………………………………………………
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 141
Figure 6…2。 A more extensive inheritance tree illustrating how functionality can be enhanced
In Figure 6…2; all of the cars are related in that they are the 530 line。 The new model is the
BMW 530xi Sports Wagon; which; from an inheritance perspective; is based on the function
ality of the BMW 530xi。 But here is the twist: the functionality of the 530xi Sports Wagon requires
you to get accust