<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <link rel="stylesheet" type="text/css" href="docs.css"> <!--[if gte IE 5]> <link href="docs_ie.css" rel="stylesheet" type="text/css"> <![endif]--> </head> <body><div id="pagecontainer"><table><tr><td width="5"> </td><td><a name="Inheritance"></a><br> <a name="outline183"></a><br><h1>7. Inheritance</h1><br> So far we have always been working with the concrete (i.e. most specific type of an object. What about subclassing and interfaces?<br> <br> To explore this, we will differentiate between different kinds of sensors.<br> <br> <table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg"> <code>using System;<br> namespace Db4odoc.Tutorial.F1.Chapter5<br> { <br> public class SensorReadout<br> {<br> DateTime _time;<br> Car _car;<br> string _description;<br> <br> public SensorReadout(DateTime time, Car car, string description)<br> {<br> _time = time;<br> _car = car;<br> _description = description;<br> }<br> <br> public Car Car<br> {<br> get<br> {<br> return _car;<br> }<br> }<br> <br> public DateTime Time<br> {<br> get<br> {<br> return _time;<br> }<br> }<br> <br> public string Description<br> {<br> get<br> {<br> return _description;<br> }<br> }<br> <br> override public string ToString()<br> {<br> return string.Format("{0}:{1}:{2}", _car, _time, _description);<br> }<br> }<br> }<br> </code></td></tr></table> <br> <br> <table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg"> <code>using System;<br> namespace Db4odoc.Tutorial.F1.Chapter5<br> { <br> public class TemperatureSensorReadout : SensorReadout<br> {<br> double _temperature;<br> public TemperatureSensorReadout(DateTime time, Car car, string description, double temperature)<br> : base(time, car, description)<br> {<br> _temperature = temperature;<br> }<br> <br> public double Temperature<br> {<br> get<br> {<br> return _temperature;<br> }<br> }<br> <br> override public string ToString()<br> {<br> return string.Format("{0} temp: {1}", base.ToString(), _temperature);<br> }<br> }<br> }<br> </code></td></tr></table> <br> <br> <table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg"> <code>using System;<br> namespace Db4odoc.Tutorial.F1.Chapter5<br> {<br> public class PressureSensorReadout : SensorReadout<br> {<br> double _pressure;<br> <br> public PressureSensorReadout(DateTime time, Car car, string description, double pressure)<br> : base(time, car, description)<br> {<br> _pressure = pressure;<br> }<br> <br> public double Pressure<br> {<br> get<br> {<br> return _pressure;<br> }<br> }<br> <br> override public string ToString()<br> {<br> return string.Format("{0} pressure: {1}", base.ToString(), _pressure);<br> }<br> }<br> }<br> </code></td></tr></table> <br> <br> Our car's snapshot mechanism is changed accordingly.<br> <br> <table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg"> <code>using System;<br> using System.Collections;<br> namespace Db4odoc.Tutorial.F1.Chapter5<br> { <br> public class Car<br> {<br> string _model;<br> Pilot _pilot;<br> IList _history;<br> <br> public Car(string model)<br> {<br> _model = model;<br> _pilot = null;<br> _history = new ArrayList();<br> }<br> <br> public Pilot Pilot<br> {<br> get<br> {<br> return _pilot;<br> }<br> <br> set<br> {<br> _pilot = value;<br> }<br> }<br> <br> public string Model<br> {<br> get<br> {<br> return _model;<br> }<br> }<br> <br> public SensorReadout[] GetHistory()<br> {<br> SensorReadout[] history = new SensorReadout[_history.Count];<br> _history.CopyTo(history, 0);<br> return history;<br> }<br> <br> public void Snapshot()<br> {<br> _history.Add(new TemperatureSensorReadout(DateTime.Now, this, "oil", PollOilTemperature()));<br> _history.Add(new TemperatureSensorReadout(DateTime.Now, this, "water", PollWaterTemperature()));<br> _history.Add(new PressureSensorReadout(DateTime.Now, this, "oil", PollOilPressure()));<br> }<br> <br> protected double PollOilTemperature()<br> {<br> return 0.1*_history.Count;<br> }<br> <br> protected double PollWaterTemperature()<br> {<br> return 0.2*_history.Count;<br> }<br> <br> protected double PollOilPressure()<br> {<br> return 0.3*_history.Count;<br> }<br> <br> override public string ToString()<br> {<br> return string.Format("{0}[{1}]/{2}", _model, _pilot, _history.Count);<br> }<br> }<br> }<br> </code></td></tr></table> <br> <br> <ul> <a name="outline184"></a><br><h2>7.1. Storing</h2><br> Our setup code has not changed at all, just the internal workings of a snapshot.<br> <br> <table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg"> <code>// storeFirstCar<br> Car car1 = new Car("Ferrari");<br> Pilot pilot1 = new Pilot("Michael Schumacher", 100);<br> car1.Pilot = pilot1;<br> db.Store(car1);</code></td><td class="lg" align="left" valign="bottom" width=43><input type='button' class='button' value='Run' onclick='window.external.RunExample("com.db4odoc.f1.chapter5.InheritanceExample", "storeFirstCar")' /></td></tr></table> <br> <br> <table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg"> <code>// storeSecondCar<br> Pilot pilot2 = new Pilot("Rubens Barrichello", 99);<br> Car car2 = new Car("BMW");<br> car2.Pilot = pilot2;<br> car2.Snapshot();<br> car2.Snapshot();<br> db.Store(car2);</code></td><td class="lg" align="left" valign="bottom" width=43><input type='button' class='button' value='Run' onclick='window.external.RunExample("com.db4odoc.f1.chapter5.InheritanceExample", "storeSecondCar")' /></td></tr></table> <br> <br> <a name="outline185"></a><br><h2>7.2. Retrieving</h2><br> 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.<br> <br> <table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg"> <code>// retrieveTemperatureReadoutsQBE<br> SensorReadout proto = new TemperatureSensorReadout(DateTime.MinValue, null, null, 0.0);<br> IObjectSet result = db.QueryByExample(proto);<br> ListResult(result);</code></td><td class="lg" align="left" valign="bottom" width=43><input type='button' class='button' value='Run' onclick='window.external.RunExample("com.db4odoc.f1.chapter5.InheritanceExample", "retrieveTemperatureReadoutsQBE")' /></td></tr></table> <br> <br> <table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg"> <code>// retrieveAllSensorReadoutsQBE<br> SensorReadout proto = new SensorReadout(DateTime.MinValue, null, null);<br> IObjectSet result = db.QueryByExample(proto);<br> ListResult(result);</code></td><td class="lg" align="left" valign="bottom" width=43><input type='button' class='button' value='Run' onclick='window.external.RunExample("com.db4odoc.f1.chapter5.InheritanceExample", "retrieveAllSensorReadoutsQBE")' /></td></tr></table> <br> <br> 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.<br> <br> <table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg"> <code>// retrieveAllSensorReadoutsQBEAlternative<br> IObjectSet result = db.QueryByExample(typeof(SensorReadout));<br> ListResult(result);</code></td><td class="lg" align="left" valign="bottom" width=43><input type='button' class='button' value='Run' onclick='window.external.RunExample("com.db4odoc.f1.chapter5.InheritanceExample", "retrieveAllSensorReadoutsQBEAlternative")' /></td></tr></table> <br> <br> And of course there's our SODA API:<br> <br> <table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg"> <code>// retrieveAllSensorReadoutsQuery<br> IQuery query = db.Query();<br> query.Constrain(typeof(SensorReadout));<br> IObjectSet result = query.Execute();<br> ListResult(result);</code></td><td class="lg" align="left" valign="bottom" width=43><input type='button' class='button' value='Run' onclick='window.external.RunExample("com.db4odoc.f1.chapter5.InheritanceExample", "retrieveAllSensorReadoutsQuery")' /></td></tr></table> <br> <br> <a name="outline186"></a><br><h2>7.3. Updating and deleting</h2><br> is just the same for all objects, no matter where they are situated in the inheritance tree.<br> <br> Just like we retrieved all objects from the database above, we can delete all stored objects to prepare for the next chapter.<br> <br> <table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg"> <code>// deleteAll<br> IObjectSet result = db.QueryByExample(typeof(Object));<br> foreach (object item in result)<br> {<br> db.Delete(item);<br> }</code></td><td class="lg" align="left" valign="bottom" width=43><input type='button' class='button' value='Run' onclick='window.external.RunExample("com.db4odoc.f1.Util", "deleteAll")' /></td></tr></table> <br> <br> <a name="outline187"></a><br><h2>7.4. Conclusion</h2><br> 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 <a href="Deep.html#Deep">next chapter </a> by looking at deep object graphs, including recursive structures.<br> <br> <a name="outline188"></a><br><h2>7.5. Full source</h2><br> <table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg"> <code>using System;<br> using System.IO;<br> using Db4objects.Db4o;<br> using Db4objects.Db4o.Query;<br> namespace Db4odoc.Tutorial.F1.Chapter5<br> { <br> public class InheritanceExample : Util<br> {<br> readonly static string YapFileName = Path.Combine(<br> Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),<br> "formula1.yap"); <br> <br> public static void Main(string[] args)<br> {<br> File.Delete(YapFileName);<br> using(IObjectContainer db = Db4oEmbedded.OpenFile(YapFileName))<br> {<br> StoreFirstCar(db);<br> StoreSecondCar(db);<br> RetrieveTemperatureReadoutsQBE(db);<br> RetrieveAllSensorReadoutsQBE(db);<br> RetrieveAllSensorReadoutsQBEAlternative(db);<br> RetrieveAllSensorReadoutsQuery(db);<br> RetrieveAllObjects(db);<br> }<br> }<br> <br> public static void StoreFirstCar(IObjectContainer db)<br> {<br> Car car1 = new Car("Ferrari");<br> Pilot pilot1 = new Pilot("Michael Schumacher", 100);<br> car1.Pilot = pilot1;<br> db.Store(car1);<br> }<br> <br> public static void StoreSecondCar(IObjectContainer db)<br> {<br> Pilot pilot2 = new Pilot("Rubens Barrichello", 99);<br> Car car2 = new Car("BMW");<br> car2.Pilot = pilot2;<br> car2.Snapshot();<br> car2.Snapshot();<br> db.Store(car2);<br> }<br> <br> public static void RetrieveAllSensorReadoutsQBE(IObjectContainer db)<br> {<br> SensorReadout proto = new SensorReadout(DateTime.MinValue, null, null);<br> IObjectSet result = db.QueryByExample(proto);<br> ListResult(result);<br> }<br> <br> public static void RetrieveTemperatureReadoutsQBE(IObjectContainer db)<br> {<br> SensorReadout proto = new TemperatureSensorReadout(DateTime.MinValue, null, null, 0.0);<br> IObjectSet result = db.QueryByExample(proto);<br> ListResult(result);<br> }<br> <br> public static void RetrieveAllSensorReadoutsQBEAlternative(IObjectContainer db)<br> {<br> IObjectSet result = db.QueryByExample(typeof(SensorReadout));<br> ListResult(result);<br> }<br> <br> public static void RetrieveAllSensorReadoutsQuery(IObjectContainer db)<br> {<br> IQuery query = db.Query();<br> query.Constrain(typeof(SensorReadout));<br> IObjectSet result = query.Execute();<br> ListResult(result);<br> }<br> <br> public static void RetrieveAllObjects(IObjectContainer db)<br> {<br> IObjectSet result = db.QueryByExample(new object());<br> ListResult(result);<br> }<br> }<br> }<br> </code></td></tr></table> <br> <br><br><div id="footer"><p align="center">Do you have any questions, suggestions or feedback? Ask your questions in the <a href="http://developer.db4o.com/Forums.aspx" target=_top>db4o forums</a>. Join the <a href="http://developer.db4o.com" target=_top>db4o community</a> for addional resources and news.<br><br><a href="http://www.db4o.com/" target=_top><small>www.db4o.com</small></a></p>.</div><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></td></tr></table></div></body></html>