OOP接口和抽象类

时间:2016-03-22 11:31:58

标签: c# oop

我正在学习C#中的OOP,但是在设计模拟大学卡系统的模拟应用程序时遇到了麻烦,该系统允许学生和员工访问某些服务/建筑物。

enter image description here

我有一个抽象类UniversityMember,其中包含公共信息,例如每个人都有名字等。我有更具体的接口,例如IStudent生成studentIds并使用enum AccessLevel类为每个学生设置门/访问级别。但是当我做的时候

public static void Main(string[] args)
{
    Student Majid = new Student();

    Majid.FName = "foo";
    Majid.LName = "hello";
    Majid.SetStudentId();
    Majid.ExpiryDate = new DateTime(2018, 09, 10);
    Majid.Type = MemberType.Student;

    Majid.setStudentLevel(AccessLevel.CharlesWilson,
                          AccessLevel.ComputerScienceBuilding,
                          AccessLevel.DavidWilson);

    PayTutionFees(Majid);
}

public static void PayTutionFees(IStudent student)
{
    //Design problem
    //student.ID  etc 
}

我使用多态,因为每个学生都实现了IStudent但是我没有访问学生信息,因为它位于UniversityMember抽象类中。我不希望界面充满重复的方法,因为它们是学生和教学人员共享的共同信息。我怎么能解决这个问题?

4 个答案:

答案 0 :(得分:3)

如果您知道IStudentIWorkingStaff等的实施者有一些共同的属性,您可以在单独的界面中描述这些属性,例如IUniversityMember

public interface IUniversityMember
{
    String ID {get;}
    // etc.
}

使现有界面(这​​意味着访问这些常见属性)扩展IUniversityMember

public interface IStudent : IUniversityMember {...}
public interface IWorkingStaff : IUniversityMember {...}

(这意味着IStudentIWorkingStaff现在都要求他们的实施者提供属性,除了他们自己的IUniversityMember界面中列出。)然后你可以使你的抽象{{ 1}}类实现这个新的UniversityMember接口。

由于你的具体类无论如何都扩展了IUniversityMemeber,它们将自动满足这个更广泛的接口,继承了UniversityMember所需的所有属性,从它们的基本抽象类开始。

通过这种方式,您可以在方法中接受IUniversityMember作为参数,并且仍然可以访问与其他类型的大学成员共有的属性。

答案 1 :(得分:1)

当您使用界面作为参数时,您无法在内部使用student.ID,因为您无法确定只有Student类会实现给定的界面。您应该只依赖于接口成员。在这种情况下,我想你只是使用错误的参数类型(正如我在评论中提到的那样)。

答案 2 :(得分:1)

问题是你没有将抽象与实现分开。如果您有更多通用类信息,对所有成员都是通用的,那么您应该在界面中声明它,例如:

public interface IUniversityMember
{
    publis string Name {get;set;}
    publis string Id {get;set;}
}

然后在IStudent界面中继承它:

public interface IStudent: IUniversityMember
{
    publis string StudentRelatedProperty {get;set;}
}

虽然您的UniversityMember课程应该实施IUniversityMember。抽象类是一个实现细节,不应该公开。

答案 3 :(得分:1)

您尝试访问IStudent.ID

<exec
    command="git fetch &amp;&amp; git diff --name-only ..origin/master"
    outputProperty="filesList"
    dir="${dir.destination}"
/>

你可以在这一点开始施展

public static void PayTutionFees(IStudent student)
{
    student.ID // at this point student is a IStudent so no ID prop available
}