代码改变世界

07继承

2012-10-20 13:56  于为源  阅读(224)  评论(0编辑  收藏  举报

到目前为止我们一直在使用具体的对象进行工作(即到多数时候是使用特定类型的具体对象)。那么,关于继承和接口将如何处理呢?

为了探究这个问题,我们将区分出不同类型的传感器以进行演示。

using System;
namespace Db4odoc.Tutorial.F1.Chapter5
{   
    public class SensorReadout
    {
        DateTime _time;
        Car _car;
        string _description;
        
        public SensorReadout(DateTime time, Car car, string description)
        {
            _time = time;
            _car = car;
            _description = description;
        }
        
        public Car Car
        {
            get
            {
                return _car;
            }
        }
        
        public DateTime Time
        {
            get
            {
                return _time;
            }
        }
        
        public string Description
        {
            get
            {
                return _description;
            }
        }
        
        override public string ToString()
        {
            return string.Format("{0}:{1}:{2}", _car, _time, _description);
        }
    }
}

 

using System;
namespace Db4odoc.Tutorial.F1.Chapter5
{   
    public class TemperatureSensorReadout : SensorReadout
    {
        double _temperature;
        public TemperatureSensorReadout(DateTime time, Car car, string description, double temperature)
            : base(time, car, description)
        {
            _temperature = temperature;
        }
        
        public double Temperature
        {
            get
            {
                return _temperature;
            }
        }
        
        override public string ToString()
        {
            return string.Format("{0} temp: {1}", base.ToString(), _temperature);
        }
    }
}
using System;
namespace Db4odoc.Tutorial.F1.Chapter5
{
    public class PressureSensorReadout : SensorReadout
    {
        double _pressure;
        
        public PressureSensorReadout(DateTime time, Car car, string description, double pressure)
            : base(time, car, description)
        {
            _pressure = pressure;
        }
        
        public double Pressure
        {
            get
            {
                return _pressure;
            }
        }
        
        override public string ToString()
        {
            return string.Format("{0} pressure: {1}", base.ToString(), _pressure);
        }
    }
}

于是,我们的汽车的快照机制也应作出相应的修改。

using System;
using System.Collections;
namespace Db4odoc.Tutorial.F1.Chapter5
{   
    public class Car
    {
        string _model;
        Pilot _pilot;
        IList _history;
        
        public Car(string model)
        {
            _model = model;
            _pilot = null;
            _history = new ArrayList();
        }
        
        public Pilot Pilot
        {
            get
            {
                return _pilot;
            }
            
            set
            {
                _pilot = value;
            }
        }
        
        public string Model
        {
            get
            {
                return _model;
            }
        }
        
        public SensorReadout[] GetHistory()
        {
            SensorReadout[] history = new SensorReadout[_history.Count];
            _history.CopyTo(history, 0);
            return history;
        }
        
        public void Snapshot()
        {
            _history.Add(new TemperatureSensorReadout(DateTime.Now, this, "oil", PollOilTemperature()));
            _history.Add(new TemperatureSensorReadout(DateTime.Now, this, "water", PollWaterTemperature()));
            _history.Add(new PressureSensorReadout(DateTime.Now, this, "oil", PollOilPressure()));
        }
        
        protected double PollOilTemperature()
        {
            return 0.1*_history.Count;
        }
        
        protected double PollWaterTemperature()
        {
            return 0.2*_history.Count;
        }
        
        protected double PollOilPressure()
        {
            return 0.3*_history.Count;
        }
        
        override public string ToString()
        {
            return string.Format("{0}[{1}]/{2}", _model, _pilot, _history.Count);
        }
    }
}

7.1 Storing(存储)

除了快照的内部工作有所改变,我们的存储代码没有任何改变。

// 存储第一辆汽车
Car car1 = new Car("Ferrari");
Pilot pilot1 = new Pilot("Michael Schumacher", 100);
car1.Pilot = pilot1;
db.Store(car1);

// 存储第二辆汽车
Pilot pilot2 = new Pilot("Rubens Barrichello", 99);
Car car2 = new Car("BMW");
car2.Pilot = pilot2;
car2.Snapshot();
car2.Snapshot();
db.Store(car2);

7.2 Retrieving(查询)

Db4o可以查询某一个类型的所有实例。要想查询特定类型的所有实例,而不管是这个类型的直接实例还是子类型实例的话,我们可以直接提供一个相应的原型就可以。(注:意思是提供父类型的原型实例,就可以将所有父类型的实例和该类型的子类型的实例都查询出来。)

// QBE查询温度传感器读数实例
SensorReadout proto = new TemperatureSensorReadout(DateTime.MinValue, null, null, 0.0);
IObjectSet result = db.QueryByExample(proto);
ListResult(result);

// QBE查询所有传感器读数实例
SensorReadout proto = new SensorReadout(DateTime.MinValue, null, null);
IObjectSet result = db.QueryByExample(proto);
ListResult(result);

这种方法不适用于一些里外的情况:如果给定要查询的类型是一个接口或者抽象类该怎么办?这里有一个小技巧:可以把类型作为QBE查询的条件。

// 另一种可供选择的查询所有传感器读数实例的QBE查询
IObjectSet result = db.QueryByExample(typeof(SensorReadout));
ListResult(result);

当然,还有SODA查询API

// SODA查询所有的传感器读数实例
IQuery query = db.Query();
query.Constrain(typeof(SensorReadout));
IObjectSet result = query.Execute();
ListResult(result);

7.3Updating and deleting

无论对象处在继承树的什么层次,更新和删除操作与前面一样。

像以前一样我们删除掉数据库中的所有对象,为下一章做准备。

// 删除所有
IObjectSet result = db.QueryByExample(typeof(Object));
foreach (object item in result)
{
    db.Delete(item);
}

7.4 结论

现在,我们已经覆盖了所有OO的基本特征,并且介绍了db4o对这些特征的处理方式。在下一章,我们将通过学习“深对象图(deep object graphs)”来完成我们的第一个关于db4o的演练,下一章的内容还包括递归结构。

 

7.5 Full source

using System;
using System.IO;
using Db4objects.Db4o;
using Db4objects.Db4o.Query;
namespace Db4odoc.Tutorial.F1.Chapter5
{   
    public class InheritanceExample : Util
    {
        readonly static string YapFileName = Path.Combine(
                               Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
                               "formula1.yap");  
        
        public static void Main(string[] args)
        {
            File.Delete(YapFileName);
            using(IObjectContainer db = Db4oEmbedded.OpenFile(YapFileName))
            {
                StoreFirstCar(db);
                StoreSecondCar(db);
                RetrieveTemperatureReadoutsQBE(db);
                RetrieveAllSensorReadoutsQBE(db);
                RetrieveAllSensorReadoutsQBEAlternative(db);
                RetrieveAllSensorReadoutsQuery(db);
                RetrieveAllObjects(db);
            }
        }
        
        public static void StoreFirstCar(IObjectContainer db)
        {
            Car car1 = new Car("Ferrari");
            Pilot pilot1 = new Pilot("Michael Schumacher", 100);
            car1.Pilot = pilot1;
            db.Store(car1);
        }
        
        public static void StoreSecondCar(IObjectContainer db)
        {
            Pilot pilot2 = new Pilot("Rubens Barrichello", 99);
            Car car2 = new Car("BMW");
            car2.Pilot = pilot2;
            car2.Snapshot();
            car2.Snapshot();
            db.Store(car2);
        }
        
        public static void RetrieveAllSensorReadoutsQBE(IObjectContainer db)
        {
            SensorReadout proto = new SensorReadout(DateTime.MinValue, null, null);
            IObjectSet result = db.QueryByExample(proto);
            ListResult(result);
        }
        
        public static void RetrieveTemperatureReadoutsQBE(IObjectContainer db)
        {
            SensorReadout proto = new TemperatureSensorReadout(DateTime.MinValue, null, null, 0.0);
            IObjectSet result = db.QueryByExample(proto);
            ListResult(result);
        }
        
        public static void RetrieveAllSensorReadoutsQBEAlternative(IObjectContainer db)
        {
            IObjectSet result = db.QueryByExample(typeof(SensorReadout));
            ListResult(result);
        }
        
        public static void RetrieveAllSensorReadoutsQuery(IObjectContainer db)
        {
            IQuery query = db.Query();
            query.Constrain(typeof(SensorReadout));
            IObjectSet result = query.Execute();
            ListResult(result);
        }
        
        public static void RetrieveAllObjects(IObjectContainer db)
        {
            IObjectSet result = db.QueryByExample(new object());
            ListResult(result);
        }
    }
}

本章相关的示例代码:代码下载