设计不好?使用抽象类集合来包含具体的孩子

时间:2019-01-29 03:59:14

标签: c# abstract-class

我想在我正在编写的最新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类的属性。我说的时候应该使用多个模型,尝试使用不同的子级具体类,例如基础票证的不同票证类型吗?想法是让一个具体的类用于日历中的约会确认,而另一个类用于支持类的事件项目。

提前了解您的想法。

1 个答案:

答案 0 :(得分:0)

我不确定我是否完全理解您的问题,但是我可以给您一些提示。这并不是真正的回应,但是将其发布为评论太混乱了。

提示:

  • 不要创建没有任何抽象属性或函数的抽象类。

    如果您需要更多的类(不应初始化其父级)的公共父级,请使用受保护的构造函数。

  • 当该父类只有一个孩子时,创建父类或抽象类没有任何意义。

  • 抽象类的真正含义是无需说明即可实现功能。

请参见“阅读器”的简单示例:

24

没有真正的实现,但是您应该明白这一点。当您不使用抽象类中的某些抽象函数时,则无需创建抽象类。请参见import React, { PureComponent } from "react"; import { Button, Form, Select } from "antd"; const { Item } = Form; const { Option } = Select; const students = [ { id: 1, fullName: "Bob Smith" }, { id: 2, fullName: "Amber Johnson" } ]; class InlineForm extends PureComponent { handleSubmit = e => { e.preventDefault(); this.props.form.validateFieldsAndScroll((err, values) => { if (!err) { alert(JSON.stringify(values, null, 4)); } }); }; render = () => { const { getFieldDecorator } = this.props.form; return ( <Form onSubmit={this.handleSubmit} layout="inline"> <Item wrapperCol={{ sm: 24 }} style={{ width: "60%", height: 60, marginBottom: 0, marginRight: 0 }} > {getFieldDecorator("studentId", { rules: [{ required: true, message: "You must select a student" }] })( <Select style={{ width: "100%" }}> {students.map(({ id, fullName }) => ( <Option key={fullName} value={id}> {fullName} </Option> ))} </Select> )} </Item> <Item wrapperCol={{ sm: 24 }} style={{ width: "40%", marginRight: 0 }}> <Button type="primary" htmlType="submit" style={{ width: "100%" }}> Register </Button> </Item> </Form> ); }; } export default Form.create({ name: "inline-form" })(InlineForm); 函数中未实现函数的使用。

属性也是如此。如果您不使用未实现的功能,那么最好使用接口。

关于您的问题:“为什么您可以看到子属性”

很简单。当您有一个父类时,您将看不到子属性。对于父类,只有父定义的方法和属性才可见。您需要重新输入您的子类,才能将其用作具有所有方法和属性的子类。

当您需要更多的孩子并且有一个功能时,使用父母是有意义的,该功能可用于具有相同属性/功能的所有孩子。