# 6. Inheritance

So far we have always been working with the concrete (i.e. most specific type of an object. What about subclassing and interfaces?
To explore this, we will differentiate between different kinds of sensors.

`Imports System
Namespace com.db4o.f1.chapter4
Public Class SensorReadout
Private _time As DateTime
Private _car As Car
Private _description As String
Public Sub New(ByVal time As DateTime, ByVal car As Car, ByVal description As String)
_time = time
_car = car
_description = description
End Sub
Public ReadOnly Property Car() As Car
Get
Return _car
End Get
End Property
Public ReadOnly Property Time() As DateTime
Get
Return _time
End Get
End Property
Public ReadOnly Property Description() As String
Get
Return _description
End Get
End Property
Public Overloads Overrides Function ToString() As String
Return String.Format("{0}:{1}:{2}", _car, _time, _description)
End Function
End Class
End Namespace
`

`Imports System
Namespace com.db4o.f1.chapter4
Public Class TemperatureSensorReadout
Inherits SensorReadout
Private _temperature As Double
Public Sub New(ByVal time As DateTime, ByVal car As Car, ByVal description As String, ByVal temperature As Double)
MyBase.New(time, car, description)
_temperature = temperature
End Sub
Public ReadOnly Property Temperature() As Double
Get
Return _temperature
End Get
End Property
Public Overloads Overrides Function ToString() As String
Return String.Format("{0} temp: {1}", MyBase.ToString(), _temperature)
End Function
End Class
End Namespace
`

`Imports System
Namespace com.db4o.f1.chapter4
Public Class PressureSensorReadout
Inherits SensorReadout
Private _pressure As Double
Public Sub New(ByVal time As DateTime, ByVal car As Car, ByVal description As String, ByVal pressure As Double)
MyBase.New(time, car, description)
_pressure = pressure
End Sub
Public ReadOnly Property Pressure() As Double
Get
Return _pressure
End Get
End Property
Public Overloads Overrides Function ToString() As String
Return String.Format("{0} pressure: {1}", MyBase.ToString(), _pressure)
End Function
End Class
End Namespace
`

Our car's snapshot mechanism is changed accordingly.

`Imports System
Imports System.Collections
Namespace com.db4o.f1.chapter4
Public Class Car
Private _model As String
Private _pilot As Pilot
Private _history As IList
Public Sub New(ByVal model As String)
_model = model
_pilot = Nothing
_history = New ArrayList()
End Sub
Public Property Pilot() As Pilot
Get
Return _pilot
End Get
Set
_pilot = value
End Set
End Property
Public ReadOnly Property Model() As String
Get
Return _model
End Get
End Property
Public Function GetHistory() As SensorReadout()
Dim history As SensorReadout() = New SensorReadout(_history.Count) {}
_history.CopyTo(history, 0)
Return history
End Function
Public Sub Snapshot()
_history.Add(New TemperatureSensorReadout(DateTime.Now, Me, "oil", PollOilTemperature()))
_history.Add(New TemperatureSensorReadout(DateTime.Now, Me, "water", PollWaterTemperature()))
_history.Add(New PressureSensorReadout(DateTime.Now, Me, "oil", PollOilPressure()))
End Sub
Protected Function PollOilTemperature() As Double
Return 0.1 * _history.Count
End Function
Protected Function PollWaterTemperature() As Double
Return 0.2 * _history.Count
End Function
Protected Function PollOilPressure() As Double
Return 0.3 * _history.Count
End Function
Public Overloads Overrides Function ToString() As String
Return String.Format("{0}[{1}]/{2}", _model, _pilot, _history.Count)
End Function
End Class
End Namespace
`

## 6.1. Storing

Our setup code has not changed at all, just the internal workings of a snapshot.

`[storeFirstCar] Dim car1 As Car = New Car("Ferrari") Dim pilot1 As Pilot = New Pilot("Michael Schumacher", 100) car1.Pilot = pilot1 db.[Set](car1)`

`[storeSecondCar] Dim pilot2 As Pilot = New Pilot("Rubens Barrichello", 99) Dim car2 As Car = New Car("BMW") car2.Pilot = pilot2 car2.Snapshot() car2.Snapshot() db.[Set](car2)`

## 6.2. Retrieving

db4o will provide us with all objects of the given type. To collect all instances of a given class, no matter whether they are subclass members or direct instances, we just provide a corresponding prototype.

`[retrieveTemperatureReadoutsQBE] Dim proto As SensorReadout = New TemperatureSensorReadout(DateTime.MinValue, Nothing, Nothing, 0) Dim result As ObjectSet = db.[Get](proto) ListResult(result)`

OUTPUT: 4 BMW[Rubens Barrichello/99]/6 : Wed Jul 05 10:33:48 CEST 2006 : water temp : 0.8 BMW[Rubens Barrichello/99]/6 : Wed Jul 05 10:33:48 CEST 2006 : oil temp : 0.30000000000000004 BMW[Rubens Barrichello/99]/6 : Wed Jul 05 10:33:48 CEST 2006 : water temp : 0.2 BMW[Rubens Barrichello/99]/6 : Wed Jul 05 10:33:48 CEST 2006 : oil temp : 0.0

`[retrieveAllSensorReadoutsQBE] Dim proto As SensorReadout = New SensorReadout(DateTime.MinValue, Nothing, Nothing) Dim result As ObjectSet = db.[Get](proto) ListResult(result)`

OUTPUT:
6
BMW[Rubens Barrichello/99]/6 : Wed Jul 05 10:33:48 CEST 2006 : oil pressure : 1.5
BMW[Rubens Barrichello/99]/6 : Wed Jul 05 10:33:48 CEST 2006 : water temp : 0.8
BMW[Rubens Barrichello/99]/6 : Wed Jul 05 10:33:48 CEST 2006 : oil temp : 0.30000000000000004
BMW[Rubens Barrichello/99]/6 : Wed Jul 05 10:33:48 CEST 2006 : oil pressure : 0.6
BMW[Rubens Barrichello/99]/6 : Wed Jul 05 10:33:48 CEST 2006 : water temp : 0.2
BMW[Rubens Barrichello/99]/6 : Wed Jul 05 10:33:48 CEST 2006 : oil temp : 0.0

This is one more situation where QBE might not be applicable: What if the given type is an interface or an abstract class? Well, there's a little trick to keep in mind: Type objects receive special handling with QBE.

`[retrieveAllSensorReadoutsQBEAlternative] Dim result As ObjectSet = db.[Get](GetType(SensorReadout)) ListResult(result)`

OUTPUT:
6
BMW[Rubens Barrichello/99]/6 : Wed Jul 05 10:33:48 CEST 2006 : oil pressure : 1.5
BMW[Rubens Barrichello/99]/6 : Wed Jul 05 10:33:48 CEST 2006 : water temp : 0.8
BMW[Rubens Barrichello/99]/6 : Wed Jul 05 10:33:48 CEST 2006 : oil temp : 0.30000000000000004
BMW[Rubens Barrichello/99]/6 : Wed Jul 05 10:33:48 CEST 2006 : oil pressure : 0.6
BMW[Rubens Barrichello/99]/6 : Wed Jul 05 10:33:48 CEST 2006 : water temp : 0.2
BMW[Rubens Barrichello/99]/6 : Wed Jul 05 10:33:48 CEST 2006 : oil temp : 0.0

And of course there's our SODA API:

`[retrieveAllSensorReadoutsQuery] Dim query As Query = db.Query() query.Constrain(GetType(SensorReadout)) Dim result As ObjectSet = query.Execute() ListResult(result)`

OUTPUT:
6
BMW[Rubens Barrichello/99]/6 : Wed Jul 05 10:33:48 CEST 2006 : oil pressure : 1.5
BMW[Rubens Barrichello/99]/6 : Wed Jul 05 10:33:48 CEST 2006 : water temp : 0.8
BMW[Rubens Barrichello/99]/6 : Wed Jul 05 10:33:48 CEST 2006 : oil temp : 0.30000000000000004
BMW[Rubens Barrichello/99]/6 : Wed Jul 05 10:33:48 CEST 2006 : oil pressure : 0.6
BMW[Rubens Barrichello/99]/6 : Wed Jul 05 10:33:48 CEST 2006 : water temp : 0.2
BMW[Rubens Barrichello/99]/6 : Wed Jul 05 10:33:48 CEST 2006 : oil temp : 0.0

## 6.3. Updating and deleting

is just the same for all objects, no matter where they are situated in the inheritance tree.
Just like we retrieved all objects from the database above, we can delete all stored objects to prepare for the next chapter.

`[deleteAll] Dim result As ObjectSet = db.[Get](GetType(Object)) For Each item As Object In result db.Delete(item) Next`

## 6.4. Conclusion

Now we have covered all basic OO features and the way they are handled by db4o. We will complete the first part of our db4o walkthrough in the next chapter by looking at deep object graphs, including recursive structures.

## 6.5. Full source

`Imports System
Imports System.IO
Imports com.db4o
Imports com.db4o.query
Namespace com.db4o.f1.chapter4
Public Class InheritanceExample
Inherits Util
Public Shared Sub Main(ByVal args As String())
File.Delete(Util.YapFileName)
Dim db As ObjectContainer = Db4oFactory.OpenFile(Util.YapFileName)
Try
StoreFirstCar(db)
StoreSecondCar(db)
RetrieveTemperatureReadoutsQBE(db)
RetrieveAllSensorReadoutsQBE(db)
RetrieveAllSensorReadoutsQBEAlternative(db)
RetrieveAllSensorReadoutsQuery(db)
RetrieveAllObjects(db)
Finally
db.Close()
End Try
End Sub
Public Shared Sub StoreFirstCar(ByVal db As ObjectContainer)
Dim car1 As Car = New Car("Ferrari")
Dim pilot1 As Pilot = New Pilot("Michael Schumacher", 100)
car1.Pilot = pilot1
db.[Set](car1)
End Sub
Public Shared Sub StoreSecondCar(ByVal db As ObjectContainer)
Dim pilot2 As Pilot = New Pilot("Rubens Barrichello", 99)
Dim car2 As Car = New Car("BMW")
car2.Pilot = pilot2
car2.Snapshot()
car2.Snapshot()
db.[Set](car2)
End Sub
Public Shared Sub RetrieveAllSensorReadoutsQBE(ByVal db As ObjectContainer)
Dim proto As SensorReadout = New SensorReadout(DateTime.MinValue, Nothing, Nothing)
Dim result As ObjectSet = db.[Get](proto)
ListResult(result)
End Sub
Public Shared Sub RetrieveTemperatureReadoutsQBE(ByVal db As ObjectContainer)
Dim proto As SensorReadout = New TemperatureSensorReadout(DateTime.MinValue, Nothing, Nothing, 0)
Dim result As ObjectSet = db.[Get](proto)
ListResult(result)
End Sub
Public Shared Sub RetrieveAllSensorReadoutsQBEAlternative(ByVal db As ObjectContainer)
Dim result As ObjectSet = db.[Get](GetType(SensorReadout))
ListResult(result)
End Sub
Public Shared Sub RetrieveAllSensorReadoutsQuery(ByVal db As ObjectContainer)
Dim query As Query = db.Query()
query.Constrain(GetType(SensorReadout))
Dim result As ObjectSet = query.Execute()
ListResult(result)
End Sub
Public Shared Sub RetrieveAllObjects(ByVal db As ObjectContainer)
Dim result As ObjectSet = db.[Get](New Object())
ListResult(result)
End Sub
End Class
End Namespace
`

--
generated by Doctor courtesy of db4objects Inc.