| # 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.