多态性:做对了
本文关键字:多态性 | 更新日期: 2023-09-27 18:30:20
我正在尝试了解 C# 中的多态/继承情况。
我现在拥有的是这些类:
Lease (the base class containing the general data)
PrivateLease (inheriting from the Lease class)
BusinessLease (inheriting from the Lease class)
我想要实现的是:
Lease lease = new PrivateLease();
这目前有效,但是执行此操作时我无法访问PrivateLease
对象的属性。至少不能不先将Lease
对象强制转换为PrivateLease
对象。
我希望Lease
对象是PrivateLease
或BusinessLease
对象的一般对象,该对象保存其中一个对象的所有数据。然后,在向数据库插入/更新/删除时,我将询问首先确定将数据插入哪些表的类型。
我有一种奇怪的感觉,以上不是解决这个问题的正确方法。有人对此有任何提示吗?:-)我在谷歌上搜索并阅读了我的编程书籍,每个人都建议使用基类的方法,然后从它继承到其他类。
任何帮助/提示将不胜感激!
提前谢谢。
编辑
应该从一开始就对此进行一些详细说明,对此感到抱歉!
上面提到的类只是保存我的 ASP.NET 解决方案的 UI 中的数据,以便通过数据访问层对数据库执行 CRUD 操作。所以基本上这些类只包含一堆属性来保存数据。即:
public class Lease
{
public int Id { get; set; }
public bool IsActive { get; set; }
public string TypeOfRental { get; set; }
public string RentalPeriod { get; set; }
public DateTime TakeoverDate { get; set; }
}
public class PrivateLease : Lease
{
public string Floor { get; set; }
public string Side { get; set; }
public int FloorSize { get; set; }
public int NumberOfRooms { get; set; }
}
等。。
PrivateLease
和 BusinessLease
类是不同的,因为现实世界中存在的租赁变量不同:-)
基本上,我可以只使用两个单独的PrivateLease
和BusinessLease
对象,但由于模型规定Address
对象可以容纳一个或多个Lease
,因此这不是一个选项。
对我来说,似乎我将在 ASP.NET 前端和 DAL 上经历一个主要的铸造地狱?:-/
不要在消费者层上决定(选择一个逻辑),而是由类本身来决定:
// or you ILease interface if a parent class will not contain any shared logic
abstract class Lease
{
public abstract void Do();
// example of shared logic
protected void Save(Lease l) { }
}
class PrivateLease : Lease
{
public override void Do() { // private logic here }
}
class BusinessLease : Lease
{
public override void Do() { // business logic here }
}
用法:
Lease l = ...
l.Do(); // execute the logic
您可能希望为对象创建创建工厂:
static class LeaseFactory<T> where T : Lease, new() // constraint to require default constructor existence
{
public static Leas Create()
{
return new T();
}
}
您在拥有基类的基本方法中是正确的。
您需要做的是将任何公共属性放在基类中。然后,如果您有不同的业务规则,则可以使用虚函数实现这些规则,称为多态函数。
abstract class Lease
{
public int MonthlyCost {get;set;}
public string CustomerName {get;set;}
// Declare that all Leases have to have an IncreaseCost method.
public abstract void IncreaseCost();
}
class PrivateLease : Lease
{
// Private leases are incremented by an absolute number (10).
public override void IncreaseCost()
{
MonthlyCost += 10;
}
}
class BusinessLease : Lease
{
// Business leases are incremented by 10%.
public override void IncreaseCost()
{
MonthlyCost *= 1.10;
}
}
// Somewhere in your code...
Lease lease = new PrivateLease();
// This call is polymorphic. It will use the actual type of the lease object.
lease.IncreaseCost();
在现代 OOD 中,您可以使用 interfaces
,用于这种情况。
编辑:
在我看来,为了避免强制转换,您可以为多种目的使用多个接口。 然后PrivateLease
和BusinessLease
可以实现适当的。
interface IWrite
{
string Data { get; set; }
void Write();
}
interface IRead
{
string Data { get; set; }
void Read();
}
public class Lease
{
//..
}
public class PrivateLease : Lease, IWrite, IRead
{
// other implementations
public string Data { get; set; }
public void Read()
{
//..
}
public void Write()
{
//..
}
}
public class BusinessLease : Lease, IRead
{
// other implementations
public string Data { get; set; }
public void Read()
{
//..
}
}
在 Lease 类中添加名为 DBUpdate 的虚拟方法,并在两个派生类中覆盖它。
假设某个实用程序类具有LeaseDBOperation Method如下所示:
public static void LeaseDBOperation (Lease anylease)
{
anyleaase.DBUpdate();
}
您可以调用此方法:
var pl = new PrivateLease();
..set all the properties of **pl**
//call this for db operations :
Utility.LeaseDBOperation(pl)
在 LeaseDBOperation 方法中,如果基于发送类型,则会调用所需类的 DBUpdate 方法。
Lease l = (Lease)sth;
if (l is PrivateLease)
{
PrivateLease p = (PrivateLease)l;
//do private logic here
}
else if (l if BussinessLease)
{
BussinessLease b = (BunessinessLease)l;
//do bussiness logic here
}