OOP and Inheritance Question

Joined
Mar 26, 2009
Messages
15
Programming Experience
Beginner
(I'm pretty new to OOP so please bear with me... )

I have a base class (called "One" for example) that has a number of public properties (e.g. Name, etc).

To create an instance of the One class I call a method in a separate controller class for example:

VB.NET:
Dim objController as New Controller
Dim objOne as One = objController.GetOne(id) ' where id is a variable of type integer

The GetOne method returns a One object populated with data (i.e. its properties are all set to some value e.g. Name = "joe" etc) and I can use it thus:

VB.NET:
If Not objOne Is Nothing Then
   Textbox1.Text = objOne.Name
End If

I now wish to create a derived class "Two" that inherits from class One but that has some additional properties (e.g. IsSomething, etc.)

What should Class Two look like, and how do I create an instance of class Two and ensure that all the properties of class One get populated?

I was thinking that Class Two should perhaps look like:

VB.NET:
Public Class Two
   Inherits One

   Private _IsSomething as Boolean
   Private _One as One

   Public ReadOnly Property IsSomething() As Boolean
      Get
         Return _IsSomething
      End Get
   End Property

   Public ReadOnly Property TwoOne() As One
      Get
         Return _One
      End Get
   End Property

   Public Sub New(ByVal Id As Integer)

      Dim objController as New Controller
      _One = objController.GetOne(id)

      _IsSomething = True ' for example

   End Sub

End Class
And I'd create an instance of it thus:

VB.NET:
Dim objTwo as New Two(id)

If Not objTwo Is Nothing Then
   Textbox1.Text = objTwo.TwoOne.Name
   CheckBox1.Checked = objTwo.IsSomething
End If

Is this the correct way of doing this i.e. do I have to call the GetOne() method in ClassTwo to populate the base class?

Thanks,

Norman
 
No, that's not correct. You're combining inheritance and composition there. Inheritance is an IS A relationship while composition is a HAS A relationship.

Consider this. A Car IS A Vehicle, while a Car HAS A SteeringWheel. The Car class inherits the Vehicle class so every Car is a Vehicle. The Car class is, in part, composed of a SteeringWheel so every Car has a SteeringWheel.

Now, in your code, this part says that Two IS A One:
VB.NET:
Inherits One
but this part says that Two HAS A One:
VB.NET:
Public ReadOnly Property TwoOne() As One
Think about it further. A LaptopComputer IS A Computer, right?
VB.NET:
Public Class LaptopComputer
    Inherits Computer
Now, when you create a LaptopComputer do you have to create a Computer first and then store that inside? If you wanted to get the processor of a laptop would you use myLaptopComputer.Computer.Processor? Of course not. A laptop IS A computer so it would just be myLaptop.Processor.

If a Two IS A One then a Two object must have its own Name property because a One object has a Name property and a Two object IS A One object.
 
Thanks for the reply. I follow your example, but in practical terms I know I'm a bit lost or at least I know I have more studying to do!
If a Two IS A One then a Two object must have its own Name property because a One object has a Name property and a Two object IS A One object.
When you're designing your Two class you don't actually have to declare the Name property inside the Two class right, by virtue of the fact that it inherits from One? To use your example of the computer and laptop i.e. you declare all the properties that are common to both inside the computer class and only properties that are unique to the laptop inside the laptop class? I'm still a bit confused as to what the methods or classes (etc) would generally look like that would populate both objects and how you'd instantiate both.
 
When you're designing your Two class you don't actually have to declare the Name property inside the Two class right, by virtue of the fact that it inherits from One? To use your example of the computer and laptop i.e. you declare all the properties that are common to both inside the computer class and only properties that are unique to the laptop inside the laptop class?
Correct. Just look at some existing classes. For instance, the Component class defines all the functionality that a design-time component requires. The Control class then extends that set of functionality and defines all the functionality that a UI control requires. The TextBoxBase class then extends that with all the functionality that an editable text field requires. The TextBox, RichTextBox and MaskedTextBox classes then each extend that in specific ways for each of those three controls. The ButtonBase class also extends the Control class and provides standard functionality for a clickable button, which is then extended further by the Button, CheckBox and RadioButton classes.
 
Thanks for the reply. I follow your example, but in practical terms I know I'm a bit lost or at least I know I have more studying to do! When you're designing your Two class you don't actually have to declare the Name property inside the Two class right, by virtue of the fact that it inherits from One?
Right. It already has a name because One has-a name because Two is-a One


VB.NET:
Class Computer
  Public NumberOfProcessors as Integer = 0
End Class

Class Laptop Inherits Computer
  Public BatteryMilliAmpereHours as Integer = 0

  Public Sub New() 'constructor
    MyBase.NumberOfProcessors = 1 'mybase isnt necessary but helps you remember it is an inherited item
    BatteryMilliAmpereHours = 7200
  End Sub
End Class

Class Server Inherits Computer
  Public RaidArraySize as Integer = 0

  Public Sub New() 'constructor
    MyBase.NumberOfProcessors = 4 'mybase isnt necessary but helps you remember it is an inherited item
    RaidArraySize = 8
  End Sub
End Class

To use your example of the computer and laptop i.e. you declare all the properties that are common to both inside the computer class and only properties that are unique to the laptop inside the laptop class?
Correct

I'm still a bit confused as to what the methods or classes (etc) would generally look like that would populate both objects and how you'd instantiate both.

Typically you'd make Computer abstract because you cannot create a "computer" you have to create one of its child types. Any class not having a constructor has one created for it by the compiler. It takes no parameters and does nothing (other than call its base constructor). It must be created because it will be called before the child constructor when the child is created


You don't instantiate both. In creating one, the other comes to be, because one IS the other. Both Server and Laptop have all the features of Computer. You can refer to anything in Computer by using MyBase from Laptop.. though its usually not necessary there may be some times you specifically use it. You will learn these later


When you make a laptop (in another class entirely, let's say ComputingDepartment) they have all the features of the parent computer and the child laptop:

Dim lp as New Laptop
lp.NumberOfProcessors = 27
lp.BatteryMilliAmpereHours = 13324321

Note that the beauty of inheritance comes in because you can treat either server or laptop as a Computer because they are both kinds of Computer. Suppose computer has an abstract method (a method with no code, but code must be written for it in the child class:


VB.NET:
Class Computer
  Public NumberOfProcessors as Integer = 0

  [B]Public MustOverride Sub MakeASound()[/B]
End Class

Class Laptop Inherits Computer
  Public BatteryMilliAmpereHours as Integer = 0

  Public Sub New() 'constructor
    MyBase.NumberOfProcessors = 1 'mybase isnt necessary but helps you remember it is an inherited item
    BatteryMilliAmpereHours = 7200
  End Sub

[B]  Public Overrides Sub MakeASound()
    PlayWav("bong.wav")
  End Sub[/B]

End Class

Class Server Inherits Computer
  Public RaidArraySize as Integer = 0

  Public Sub New() 'constructor
    MyBase.NumberOfProcessors = 4 'mybase isnt necessary but helps you remember it is an inherited item
    RaidArraySize = 8
  End Sub

[B]  Public Overrides Sub MakeASound()
    PlayBeep()
  End Sub[/B]
End Class

Laptops have sound cards, speakers, multimedia capabilities; servers dont, but they can play a beep from their speaker.

If we say:

Dim c as Computer

c = New Laptop 'remember a we can assign a laptop into a computer variable because any child can be assigned to a variable of its parent
c.MakeASound() ' a bong is heard

c = New Server
c.MakeASound() ' a beep is heard


This is great, because it allows us to write code now that someone can expand in the future and we dont change our code to make it able to call theirs. If this example is a bit weak, consider zip, rar, 7zip, etc compression. The compression ratio is getting better with new algorithms

If we made a Compressor.Compress(file) method but didnt write the compressor code, our code would just call that routine and not care how the file was compressed. Then someone write s ZIPCompressor (Inherits Compressor) that compressses as zips. Then someone else writes an RARCompressor (Inherits Compressor) that compresses as RAR (better than zip)

Our code just has Compressor.Compress.. and because Compressor (like Computer) can be either ZipCompressor(like laptop) or RARCompressor(like server), calling Compressor.Compress will cause the file to be compressed as RAR if Compressor is actually an instance of RARCompressor etc
 
Last edited:
Thanks for the replies (jmcilhinney and cjard), I really appreciate the time taken to respond. I certainly see the power and flexibility of OOP - it will just take (me!) some time to structure things correctly.

[cjard] I have one finally question for the moment that I hope you could help me with. In your example involving Computer, Laptop and Server I see that in the Constructor for Laptop and Server you set some properties.

Imagine that the values for these properties (e.g. BatteryMilliAmpereHours and RaidArraySize) are coming from a database and that you had an additional class that was derived from Laptop (as opposed to Computer - I'm not sure if this is a valid case but anyway...). Is it common/good practice for each layer/derived class to involve a call to the database? e.g. the constructor for Laptop would involve a call to the database that would get all the properties unique for Laptop and the constructor for the class that derives from Laptop would get all the properties unique to it? I can see that you'd want to have a call to the database in both depending on whether you wanted to create an instance of Laptop or your new class, but isn't creating an instance of this new class less efficient (for want of a better term) as you have two calls to the database? In other words is there a way of creating an instance of the new class (i.e. the one derived from Laptop) that involves only one call to the database?

Thanks
 
Is it common/good practice for each layer/derived class to involve a call to the database?
No, for a similar reason that bucket manufacturers don't fill their buckets with soapy water before they sell them to you; you might want a bucket for storing milk in, and it's all contaminated if you bought it (it is supplied to you declared as "ready for use") with soapy water in.

The purpose of a constructor is that, when it is done, the object is suitable for use in any of the contexts within which it might be found.

In MVC concept theory your classes here are data containers. You would have a separate class push/pull data between them and a database


e.g. the constructor for Laptop would involve a call to the database that would get all the properties unique for Laptop and the constructor for the class that derives from Laptop would get all the properties unique to it?
Contructor would set values, but they would be suitable defaults, NOT specifics. Remember you are looking to get your object to a usable state, not a complete state. What happens in future if you want to reuse your data classes for another project, for another company, who don't have that database?
 
Back
Top