2

我试图弄清楚 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对象成为 aPrivateLeaseBusinessLeaseobject 的一般对象,该对象包含其中一个对象的所有数据。然后,在向数据库插入/更新/删除时,我会先询问它是哪种类型,以确定将数据插入到哪些表中。

我有一种奇怪的感觉,上面不是解决这个问题的正确方法。有人对此有任何提示吗?:-) 我在谷歌上搜索并阅读了我的编程书籍,每个人都建议这种方法拥有一个基类,然后从它继承到其他类。

非常感谢任何帮助/提示!

提前致谢。

编辑

应该从一开始就详细说明这一点,我很抱歉!

上面提到的类只是从我的 ASP.NET 解决方案的 UI 中保存数据,以通过数据访问层对数据库执行 CRUD 操作。所以基本上这些类只包含一堆保存数据的属性。IE:

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; }
}

ETC..

PrivateLease和类是不同的BusinessLease,因为现实世界中存在不同的租赁变量:-)

基本上我可以只使用两个单独的PrivateLeaseandBusinessLease对象,但是由于模型规定一个Address对象可以容纳一个或多个Leases,所以这不是一个选择。

对我来说,似乎我将在 ASP.NET 前端和 DAL 上经历一次重大的铸造地狱?:-/

4

5 回答 5

4

不要在消费者层决定(选择逻辑),而是让类自己决定:

// 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();
    }
}
于 2012-04-06T11:03:46.797 回答
3

您在拥有基类的基本方法上是正确的。

您需要做的是将任何公共属性放在基类中。然后,如果您有不同的业务规则,则可以使用虚函数来实现这些规则,并以多态方式调用它们。

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();
于 2012-04-06T10:58:35.870 回答
1

在现代 OOD 中,您可以使用interfaces, 来应对这种情况。

编辑:

在我看来,为了避免强制转换,您可以有多个接口用于多种用途。然后可以实施适当的PrivateLeaseBusinessLease

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()
    {
        //..
    }
}
于 2012-04-06T11:03:34.640 回答
0

在 Lease 类中添加名为 DBUpdate 的虚拟方法,并在两个派生类中覆盖它。

假设某个 Utility 类具有 LeaseDBOperation 方法,如下所示:

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 方法中,如果根据类型 send ,将调用所需类的 DBUpdate 方法。

于 2012-04-06T16:19:57.443 回答
-1
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
}
于 2012-04-06T10:59:59.780 回答