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.