Inheritance / interfaces / design patterns can be applied to this
problem but would need to be approached differently than above.
From the description you seem to have a set of items; some of which can
can contain other items
Box => Container
Bag => Container
Bulb => Non-container
All of these items have a color, and the apparent color of a container
depends upon the contents (if any).
This is a pretty good fit for the Composite Design Pattern (see notes
below) and can be implemented in VB.Net using both interfaces and
inheritance.
1) IColoredComponent (see code below)
Provides a common interface for accessing containers and objects.
2) ColoredContainer
Implementation of a container object. All containers are black when
empty and this implementation assumes that the apparent color
combinations do
not change from container to container (e.g. if a bag contains a red
object then it appears purple, and if a box contains a red object then
it also appears purple)
NOTE: This makes it simpler for the example (we only need one class for
box and bag) but not required. We could derive box and bag classes
from this class and override the MaskColor() function in each.
3) ColoredObject
Implementation of an on-container object. We will derive all objects
from this.
NOTE: The Contents() property is not relevant for this but needs to be
implemented as it is part of the Interface - this is a known trade off
with the composite pattern
4) Bulb
Inherits from ColoredObject and is red.
COMPOSITE DESIGN PATTERN
A Design Pattern is a shape that can be applied to many recurring
problems. The seminal book about Patterns is the Gamma one (see
references) but there are lots of books out there about the topic.
The Composite Pattern is used where we have items that can be
stand-alone or can be made up of other similar items. 'Made up of' can
be extended to mean 'contain' - so it can be applied to this problem.
PROBLEMS:
This is a lot of work for just the colors.
Presumably you will have lots of other functionality for the items and
you may want to use the containers and non-containers interchangeabley
in some context (e.g. list the contents of a room).
The code as is useful as an example for this small problem but would
need a lot of changes if this is only part of a problem domain.
Those changes are totally dependent upon the problem and out of the
range of a small answer.
LEARNING:
If you are new to VB.Net and OO and want to make use of all of VB.Net's
abilities (and not just write VB6 using the VB.Net compiler) then I'm
afraid that you have a lot of reading ahead of you.
The Design Patterns book is a must-have for OO developers - problem is
it not a good book to start on.
The Design Patterns in VB.Net is more accessible that the Gamma book
and is pretty good, but is aimed at intermediate to advanced levels.
All my early OO learning was in C++ so I don't know any good starter
VB.Net books that cover OO design well.
Try a search through this NG for book recommendations but focus on ones
trying to teach OO concepts. There are myriad books covering how to
draw controls on screens and read/write from databases using ADO.NET
and ... all the mechanical tasks, but fewer that talk about good ways
to design applications.
Alan.
REFERENCES
"Design Patterns: Elements of Reusable Object-Oriented Software",
Gamma et al. ISBN 0-201-63361-2
"Professional Design Patterns in VB.Net: Building Adaptable
Applications", Fischer et al. ISBN 1-59059-274-3
SOURCE CODE
'-------------------------------------------------
' Application class
Class App
Shared Sub Main()
Dim aBulb As New Bulb
Dim aBag As New ColoredContainer
Dim aBox As New ColoredContainer
System.Console.WriteLine("The bulb is " + aBulb.Color.ToString)
System.Console.WriteLine("The Empty bag is " +
aBag.Color.ToString)
System.Console.WriteLine("The Empty box is " +
aBox.Color.ToString)
aBox.Contents = aBag
System.Console.WriteLine("The Box containing an empty bag is "
+ aBox.Color.ToString)
aBag.Contents = aBulb
System.Console.WriteLine("The Bag containing a bulb is " +
aBag.Color.ToString)
System.Console.WriteLine("The Box containing a bag containing a
bulb is " + aBox.Color.ToString)
System.Console.ReadLine() ' pauses the display, press enter
to continue
End Sub
End Class
'-------------------------------------------------
' IColoredComponent
Public Interface IColoredComponent
ReadOnly Property Color() As System.Drawing.Color
Property Contents() As IColoredComponent
End Interface
'-------------------------------------------------
' ColoredContainer
Public Class ColoredContainer
Implements IColoredComponent
Private Const DEFAULT_COLOR As System.Drawing.KnownColor =
System.Drawing.KnownColor.Black
Public Sub New()
_color = Color.FromKnownColor(DEFAULT_COLOR)
_colorCombinations = GetColorCombinations()
End Sub
#region "IColoredComponent Implementation"
Public ReadOnly Property Color() As System.Drawing.Color Implements
IColoredComponent.Color
Get
Dim ret As System.Drawing.Color = _color
If (Not Contents Is Nothing) Then
ret = MaskColor(Contents)
End If
Return ret
End Get
End Property
Public Property Contents() As IColoredComponent Implements
IColoredComponent.Contents
Get
Return _contents
End Get
Set(ByVal Value As IColoredComponent)
_contents = Value
End Set
End Property
#end region
Protected Overridable Function MaskColor( _
ByVal contents As IColoredComponent _
) As System.Drawing.Color
Dim ret As System.Drawing.Color = contents.Color
If (_colorCombinations.Contains(contents.Color)) Then
ret = CType(_colorCombinations(contents.Color),
System.Drawing.Color)
End If
Return ret
End Function
Private Function GetColorCombinations() As
System.Collections.Hashtable
Dim ret As New System.Collections.Hashtable
ret.Add(Color.Red, Color.Purple)
ret.Add(Color.Black, Color.Pink)
ret.Add(Color.Purple, Color.Brown)
Return ret
End Function
Private _color As System.Drawing.Color
Private _contents As IColoredComponent
Private _colorCombinations As System.Collections.Hashtable
End Class
'-------------------------------------------------
' ColoredObject
Public Class ColoredObject
Implements IColoredComponent
Private Const DEFAULT_COLOR As System.Drawing.KnownColor =
System.Drawing.KnownColor.Black
Public Overridable ReadOnly Property Color() As
System.Drawing.Color Implements IColoredComponent.Color
Get
Return System.Drawing.Color.FromKnownColor(DEFAULT_COLOR)
End Get
End Property
Public Property Contents() As IColoredComponent Implements
IColoredComponent.Contents
Get
Debug.Assert(False, "This does nothing in the ColoredObject
class")
End Get
Set(ByVal Value As IColoredComponent)
Debug.Assert(False, "This does nothing in the ColoredObject
class")
End Set
End Property
End Class
'-------------------------------------------------
' Bulb
Public Class Bulb
Inherits ColoredObject
Private Const DEFAULT_COLOR As System.Drawing.KnownColor =
System.Drawing.KnownColor.Red
Public Overrides ReadOnly Property Color() As System.Drawing.Color
Get
Return System.Drawing.Color.FromKnownColor(DEFAULT_COLOR)
End Get
End Property
End Class