根据测试用例定义class
Define class based on test case
谁能告诉我如何定义 class 学生,使最后一个测试用例得到满足。
我无法理解最后一个函数 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());
}
谢谢
我从评论中得知您正在完成一些测试驱动开发 (TDD) 练习,并且您在理解此示例时遇到困难。考虑到这一点,我是这样看的:
- 测试中发生的第一件事是,当您创建
Student
的实例时,它被分配给类型为 User
的变量。这个 可以 有不同的工作方式,但最明显的解释是 User
是基础 class,并且 Student
继承 User
.
- 接下来的两个语句直接调用
student
变量上的方法。因为这个变量的类型是User
,那些方法一定存在于User
class中。同样,这有多种实际可行的方法,但最简单的是假设这些方法需要 return 的值实际上存储在 User
class.
这两点将我们引向 User
class,看起来像这样:
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
变量转换为 class Student
。另请注意,此方法预期 return studentId
中的值并且 而不是 basicId
中的值,这是基础 class 的 GetId()
方法应该是 return.
所以我们有相同的方法名称,用于相同的对象实例,但根据对象的 编译时 类型(又名 "static type").这与 运行-time 类型相反,后者是对象的实际类型。
鉴于此,我们必须在Student
class中声明一个新的GetId()
方法,当然还要提供一种方法让它return不同的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
class 有一个名称完全相同的方法,您将用您的方法隐藏 class 的方法新 GetId()
方法。因此,需要 new
关键字来避免任何编译时警告。
我个人的偏好是避免方法隐藏总是。它几乎总是错误的设计选择,只有在某些外部需求强制使用它时才应使用它。
(注意上面classes中的字段被标记为readonly
。测试中没有任何内容要求如此,但测试中也没有任何内容阻止它. 我的偏好是使字段 readonly
除非它们不能,因此在这里使用 readonly
).
谁能告诉我如何定义 class 学生,使最后一个测试用例得到满足。 我无法理解最后一个函数 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());
}
谢谢
我从评论中得知您正在完成一些测试驱动开发 (TDD) 练习,并且您在理解此示例时遇到困难。考虑到这一点,我是这样看的:
- 测试中发生的第一件事是,当您创建
Student
的实例时,它被分配给类型为User
的变量。这个 可以 有不同的工作方式,但最明显的解释是User
是基础 class,并且Student
继承User
. - 接下来的两个语句直接调用
student
变量上的方法。因为这个变量的类型是User
,那些方法一定存在于User
class中。同样,这有多种实际可行的方法,但最简单的是假设这些方法需要 return 的值实际上存储在User
class.
这两点将我们引向 User
class,看起来像这样:
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
变量转换为 class Student
。另请注意,此方法预期 return studentId
中的值并且 而不是 basicId
中的值,这是基础 class 的 GetId()
方法应该是 return.
所以我们有相同的方法名称,用于相同的对象实例,但根据对象的 编译时 类型(又名 "static type").这与 运行-time 类型相反,后者是对象的实际类型。
鉴于此,我们必须在Student
class中声明一个新的GetId()
方法,当然还要提供一种方法让它return不同的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
class 有一个名称完全相同的方法,您将用您的方法隐藏 class 的方法新 GetId()
方法。因此,需要 new
关键字来避免任何编译时警告。
我个人的偏好是避免方法隐藏总是。它几乎总是错误的设计选择,只有在某些外部需求强制使用它时才应使用它。
(注意上面classes中的字段被标记为readonly
。测试中没有任何内容要求如此,但测试中也没有任何内容阻止它. 我的偏好是使字段 readonly
除非它们不能,因此在这里使用 readonly
).