4.3 Containment

only for RuBoard

Containment indicates that one object contains another. Example 4-3 shows a hierarchy of contained classes, each nested within the other; the CreditCard object contains a BillingInfo object, which in turn contains an Address object.

The contained object, if it is used only within the parent object, can be declared as Private . Being restrictive (in terms of scope) at the class level is as important as being restrictive within the class itself. Don't make the class available if it is not needed. Here, Address is an object that could be used by several other classes, such as Order , ShippingInfo , or Invoice . BillingInfo is restricted to the payment and should not exist outside of it.

Example 4-3. Containment relationships
 Public MustInherit Class Payment   'Payment data End Class     Public Class Address   'Address1, Address2   'City, ST, Zip End Class     Public Class CreditCard : Inherits Payment      Private Class BillingInfo     Private myAddress As Address     'Methods to get to address here   End Class      Private myBillingInfo As BillingInfo     End Class 

Remember that the classes represent a has-a relationship between the parent class and the child class or classes.

The exception to this rule is the various collection classes that contain a type of an object. In this case, the container's primary behavior is to insert, remove, and maintain the objects it contains.

The same rule regarding accessibility that applies to member data also applies to a contained class; it should be private. The outer class uses the inner class, but the relationship between the two classes should be exposed only through a property.

The containing class should know what it contains, but a contained class should not know what contains it; the contained class should not use the container class in a way that exposes the type of container. Doing so could create a dependency between the two classes and possibly prevent them from being reused.

Many classes in .NET are sealed; they have been declared NotInheritable . They are declared NotInheritable because of performance considerations; it is not a diabolical plot to prevent reuse in the .NET library. In many cases, if a class is sealed, methods that would normally be virtual (determined at runtime) can be inlined by the compiler. In situations like this, containment allows the features of a class to be extended.

To see how this works, consider strings. If you have used VB for any considerable amount of time, you probably have a few string functions from ancient times, before strings were object-oriented. Supposed you'd like to modify the String class to include your old favorites. Guess what? The String class is final, so you're out of luck.


Containment is a viable alternative to inheritance in this circumstance. You probably don't need every single public method available from a String , so wrap the ones you do need and delegate to the contained String . This concept is illustrated in Example 4-4, which defines a class called XString that contains a String . The class provides a method called WrapTag , which wraps the string in an XML tag and returns the result. It also provides a Length property that delegates to the internal String class' Length property.

Example 4-4. Using containment for final .NET classes
 Imports System     Public Class XString       Private myString As String       Public Sub New(value As String)     Me.myString = value   End Sub      'New proprietary string function   Public Function WrapTag(ByVal tagName As String) As String     Return String.Format("<{0}>{1}</{2}>", _                           tagName, _                           Me.myString, _                           tagName)   End Function       'Wrap Length property of String   Public ReadOnly Property Length( ) As Integer     Get       Return myString.Length     End Get   End Property     End Class     Friend Class Test   Public Shared Sub Main( )     Dim t As New XString("test")     Console.WriteLine(t.WrapTag("center"))   End Sub End Class 

Contained objects that share the same scope should never be in a uses relationship with one another.

only for RuBoard

Object-Oriented Programming with Visual Basic. Net
Object-Oriented Programming with Visual Basic .NET
ISBN: 0596001460
EAN: 2147483647
Year: 2001
Pages: 112
Authors: J.P. Hamilton

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net