有人可以告诉我如何定义类Student,以便满足最后一个测试用例。 我无法理解最后一个函数GetId()的方法实现。
public const int basicId = 12345;
public const int studentId = 88888;
public const string sampleName = "User Name";
[TestMethod]
public void StudentIsInitializedCorrectly()
{
User student = new Student(sampleName, basicId, studentId);
Assert.AreEqual(sampleName, student.GetName());
Assert.AreEqual(basicId, student.GetId());
Assert.AreEqual(studentId, ((Student)student).GetId());
}
由于
答案 0 :(得分:3)
我从评论中了解到您正在进行一些测试驱动开发(TDD)练习,并且您无法理解这个示例。所以考虑到这一点,这就是我看待它的方式:
Student
的实例时,会将其分配给类型为User
的变量。这个可以工作的方式不同,但最明显的解释是User
是基类,而Student
继承User
。student
变量上的方法。由于此变量的类型为User
,因此这些方法必须存在于User
类中。同样有多种方法可以实际工作,但最简单的方法是假设这些方法需要返回的值实际上存储在User
类中。这两点引导我们进入User
类看起来像这样:
class User
{
private readonly string _name;
private readonly int _id;
public User(string name, int id)
{
_name = name;
_id = id;
}
public string GetName() { return _name; }
public int GetId() { return _id; }
}
以上确保当我们通过类型为User
的变量查看对象实例时,我们仍然可以调用GetName()
和GetId()
方法,并获取值期望的。
现在我们来到该方法的第三次也是最后一次测试。请注意,在调用方法之前,此测试会将student
变量强制转换为类Student
。另请注意,此方法应返回studentId
中的值和而不是 basicId
中的值,这是基类的GetId()
方法的值应该回来。
所以我们有相同的方法名,在同一个对象实例上使用,但根据对象的编译时类型(又名“静态类型”),它应该表现不同。这与运行时类型相反,后者是对象的实际类型。
鉴于此,我们必须在GetId()
类中声明一个新的Student
方法,当然还提供了一种方法来返回在对象初始化期间使用的不同ID值:
class Student : User
{
private readonly int _id;
public Student(string name, int basicId, int studentId)
: base(name, basicId)
{
_id = studentId;
}
public new int GetId() { return _id; }
}
一个问题是,鉴于我们已经知道User
类有一个具有完全相同名称的方法,您将使用新的GetId()
方法隐藏该类的方法。因此,需要new
关键字来避免任何编译时警告。
我个人的偏好是避免方法隐藏始终。它几乎总是错误的设计选择,只有在被某些外部要求强制进入时才能使用。
(请注意,上述类中的字段标记为readonly
。测试中没有任何内容需要这样的情况,但测试中也没有任何内容可以阻止它。我的偏好是创建字段readonly
除非他们不能,因此在这里使用readonly
。