[英]Bad Design? Use Abstract Class Collection to Include Concrete Children
我想在我正在编写的最新Web应用程序中正确探索/理解抽象类的实现。 但是,虽然我可以用具体类的值实例化一个抽象类令人惊讶,但我想知道这是否不是一种好方法,因为我似乎无法在儿童具体课程。
我设法创建了一个包含两个具体孩子的IList的IEnumerable基类集合。 虽然具体子级共享相同的类型,但我的想法是在需要时在网页中调用具体子级属性。 当然,我觉得这种设计并不是实现目标的真正方法。
抽象类的类:
public abstract class MasterTicket
{
public Guid id{ get; set; }
public DateTime openTime{ get; set; }
public DateTime closeTime{ get; set; }
public bool active{ get; set; }
public string summary{ get; set; }
public string description{ get; set; }
public DateTime updateTime{ get; set; }
//TODO: Create foreign key relationship to user model
public Guid userUpdateId{ get; set; }
//TODO: Create foreign key relationship for tickets from other systems
public Guid externalAppId{ get; set; }
//TODO: Create foreign key relationship to user model
public Guid userOpenId{ get; set; }
public Guid userOwnerId{ get; set; }
public int timesUpdated{ get; set; }
public DateTime expectedCompletionTime{ get; set; }
public DateTime actualCompletionTime{ get; set; }
public List<MasterTicketItem> masterTicketItems{ get; set; }
}
具体孩子班级:
public class ApptTaskTicket : MasterTicket
{
public DateTime currentApptTime;
public string patientName;
//TODO: Create foreign relationship
public Guid subjectPrsnlId;
public string patientPhone;
public string patientEmail;
public string preferredContactMethod;
}
控制器示例:
public class QueueController : Controller
{
private static readonly IList<MasterTicket> tickets;
private static readonly IEnumerable<MasterTicket> combined;
static QueueController()
{
tickets = new List<MasterTicket>
{
new ApptTaskTicket
{
id = Guid.NewGuid(),
summary = "Foopy",
description = "Please set up Foop Dawg."
},
new ApptTaskTicket
{
id = Guid.NewGuid(),
summary = "Milk man",
description = "Milkman here I come"
},
new ApptTaskTicket
{
id = Guid.NewGuid(),
summary = "InMode Presentation",
description = "Upcoming presentation next month"
},
};
CalendarQuickStart eventFetcher = new CalendarQuickStart();
IList<MasterTicket> addAppts = eventFetcher.LoadAppointmentTasks();
combined = tickets.Concat(addAppts);
tickets.Concat(addAppts);
}
// GET: Queue
public ActionResult Queue()
{
return View(combined);
}
}
查看页面以列表的形式呈现此列表:
@model IEnumerable<AffirmativeServiceSystem.Models.MasterTicket>
@{
ViewBag.Title = "Queue";
}
<h2>Queue</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
@*<th>
@Html.DisplayNameFor(model => model.openTime)
</th>
<th>
@Html.DisplayNameFor(model => model.closeTime)
</th>
<th>
@Html.DisplayNameFor(model => model.active)
</th>*@
<th>
@Html.DisplayNameFor(model => model.summary)
</th>
<th>
@Html.DisplayNameFor(model => model.description)
</th>
@*<th>
@Html.DisplayNameFor(model => model.updateTime)
</th>
<th>
@Html.DisplayNameFor(model => model.userUpdateId)
</th>
<th>
@Html.DisplayNameFor(model => model.externalAppId)
</th>
<th>
@Html.DisplayNameFor(model => model.userOpenId)
</th>
<th>
@Html.DisplayNameFor(model => model.userOwnerId)
</th>
<th>
@Html.DisplayNameFor(model => model.timesUpdated)
</th>
<th>
@Html.DisplayNameFor(model => model.expectedCompletionTime)
</th>
<th>
@Html.DisplayNameFor(model => model.actualCompletionTime)
</th>*@
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
@*<td>
@Html.DisplayFor(modelItem => item.openTime)
</td>
<td>
@Html.DisplayFor(modelItem => item.closeTime)
</td>
<td>
@Html.DisplayFor(modelItem => item.active)
</td>*@
<td>
@Html.DisplayFor(modelItem => item.summary)
</td>
<td>
@Html.DisplayFor(modelItem => item.description)
</td>
@*<td>
@Html.DisplayFor(modelItem => item.updateTime)
</td>
<td>
@Html.DisplayFor(modelItem => item.userUpdateId)
</td>
<td>
@Html.DisplayFor(modelItem => item.externalAppId)
</td>
<td>
@Html.DisplayFor(modelItem => item.userOpenId)
</td>
<td>
@Html.DisplayFor(modelItem => item.userOwnerId)
</td>
<td>
@Html.DisplayFor(modelItem => item.timesUpdated)
</td>
<td>
@Html.DisplayFor(modelItem => item.expectedCompletionTime)
</td>
<td>
@Html.DisplayFor(modelItem => item.actualCompletionTime)
</td>*@
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.id }) |
@Html.ActionLink("Details", "Details", new { id=item.id }) |
@Html.ActionLink("Delete", "Delete", new { id=item.id })
</td>
</tr>
}
</table>
以后可以根据需要包括日历代码功能,但是现在我认为还可以。
我希望能够调用子具体类的抽象属性和具体属性,但实际上,当我尝试使用Intellisense编写代码生成的视图页面时,我只看到基本MasterTicket类的属性。 我说的时候应该使用多个模型,尝试使用不同的子级具体类,例如基础票证的不同票证类型吗? 想法是让一个具体的类用于日历中的约会确认,而另一类用于支持类事件。
提前欣赏您的想法。
我不确定我是否完全理解您的问题,但是我可以给您一些提示。 这并不是真正的回应,但是将其发布为评论太乱了。
提示:
不要创建没有任何抽象属性或函数的抽象类。
当您需要更多类的公共父对象(不应初始化父对象)时 ,请使用受保护的构造函数。
当该父级只有一个孩子时,创建父级或抽象类没有任何意义。
抽象类的真正含义是无需说明即可实现功能。
请参阅以下简单的“阅读器”示例:
public abstract class Reader
{
public int ReadByte()
{
byte[] value = new byte[1];
int read = Read(value, 0, 1);
if (read == 0)
{
return -1;
}
return value[0];
}
public abstract int Read(byte[] value, int offset, int count);
}
public class DiskReader : Reader
{
// TODO: implement reading from disk
public override int Read(byte[] value, int offset, int count) => throw new System.NotImplementedException();
}
public class PortReader : Reader
{
// TODO: implement reading from serial port
public override int Read(byte[] value, int offset, int count) => throw new System.NotImplementedException();
}
public class NetworkReader : Reader
{
// TODO: implement reading from network connection
public override int Read(byte[] value, int offset, int count) => throw new System.NotImplementedException();
}
没有真正的实现,但是您应该明白这一点。 当您不使用抽象类中的某些抽象函数时,则无需创建抽象类。 请参见ReadByte
函数中未实现函数的使用。
属性也是如此。 当您不使用未实现的功能时,最好使用接口。
对于您的问题:“为什么您可以看到子属性”
很简单。 当您有一个父类时,您将看不到子属性。 对于父类,只有父定义的方法和属性才可见。 您需要重新键入您的子类,以将其用作具有所有方法和属性的子类。
当您需要更多的孩子并且有一个功能时,使用父母是有意义的,该功能可用于具有相同属性/功能的所有孩子。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.