C# OOP实践中关于继承的困惑
C# OOP practice confusion regarding inheritance
我正在阅读我的一门 C# 编程课程 material。代码本身看懂了,但是不太明白导师为什么要这样组织class
namespace GradeBook
{
public delegate void GradeAddedDelegate(object sender, EventArgs args);
public class NamedObject
{
public NamedObject(string name)
{
Name = name;
}
public string Name
{
get;
set;
}
}
public interface IBook
{
void AddGrade(double grade);
Statistics GetStatistics();
string Name { get; }
event GradeAddedDelegate GradeAdded;
}
public abstract class Book : NamedObject, IBook
{
public Book(string name) : base(name)
{
}
public abstract event GradeAddedDelegate GradeAdded;
public abstract void AddGrade(double grade);
public abstract Statistics GetStatistics();
}
public class DiskBook : Book
{
public DiskBook(string name) : base(name)
{
}
public override event GradeAddedDelegate GradeAdded;
public override void AddGrade(double grade)
{
using(var writer = File.AppendText($"{Name}.txt"))
{
writer.WriteLine(grade);
if(GradeAdded != null)
{
GradeAdded(this, new EventArgs());
}
}
}
public override Statistics GetStatistics()
{
var result = new Statistics();
using(var reader = File.OpenText($"{Name}.txt"))
{
var line = reader.ReadLine();
while(line != null)
{
var number = double.Parse(line);
result.Add(number);
line = reader.ReadLine();
}
}
return result;
}
}
上面的代码片段是普通学生的成绩簿。
- class
NameObject
定义了一个属性Name
和一个初始化器,很容易理解。
- 他把所有的方法都放在一个接口
IBook
里,还有一个class叫Book
,继承自NameObject
class和接口IBook
。我假设他故意将属性和方法、事件分开。这是正确的吗?
- 在
Book
class中,初始化public Book(string name) : base(name)
。我知道 base 正在定义一个引用类型。我对 name
参数有点困惑。是指NameObject
中的属性Name
吗?
- DiskBook 是 Book 的子class,初始化程序
public Book(string name) : base(name)
正在传递引用 name
作为最后一个。这里的name
是否也指NameObject中的name
属性?
提前致谢。
从逻辑上讲,很多东西都可以是NamedObject
。他说 Book
是 IBook
,也是 NamedObject
。想象一下添加一个 Person
class。 Person
将是 NamedObject
,但不是 IBook
。因此,您可以重用基础 class 而无需将其绑定到 Book
使用 : base(name)
表示 call the constructor on the base class with this parameter
。所以你可以确定 NamedObject
的构造函数将使用字符串值调用,设置 Name
属性。从 Book
构造函数中排除 : base(name)
将导致编译器错误,因为基础 class 没有无参数构造函数。
以同样的方式,DiskBook
使用 : base(name)
调用 Book
上的构造函数,后者又调用 NamedObject
上的构造函数.
我正在阅读我的一门 C# 编程课程 material。代码本身看懂了,但是不太明白导师为什么要这样组织class
namespace GradeBook
{
public delegate void GradeAddedDelegate(object sender, EventArgs args);
public class NamedObject
{
public NamedObject(string name)
{
Name = name;
}
public string Name
{
get;
set;
}
}
public interface IBook
{
void AddGrade(double grade);
Statistics GetStatistics();
string Name { get; }
event GradeAddedDelegate GradeAdded;
}
public abstract class Book : NamedObject, IBook
{
public Book(string name) : base(name)
{
}
public abstract event GradeAddedDelegate GradeAdded;
public abstract void AddGrade(double grade);
public abstract Statistics GetStatistics();
}
public class DiskBook : Book
{
public DiskBook(string name) : base(name)
{
}
public override event GradeAddedDelegate GradeAdded;
public override void AddGrade(double grade)
{
using(var writer = File.AppendText($"{Name}.txt"))
{
writer.WriteLine(grade);
if(GradeAdded != null)
{
GradeAdded(this, new EventArgs());
}
}
}
public override Statistics GetStatistics()
{
var result = new Statistics();
using(var reader = File.OpenText($"{Name}.txt"))
{
var line = reader.ReadLine();
while(line != null)
{
var number = double.Parse(line);
result.Add(number);
line = reader.ReadLine();
}
}
return result;
}
}
上面的代码片段是普通学生的成绩簿。
- class
NameObject
定义了一个属性Name
和一个初始化器,很容易理解。 - 他把所有的方法都放在一个接口
IBook
里,还有一个class叫Book
,继承自NameObject
class和接口IBook
。我假设他故意将属性和方法、事件分开。这是正确的吗? - 在
Book
class中,初始化public Book(string name) : base(name)
。我知道 base 正在定义一个引用类型。我对name
参数有点困惑。是指NameObject
中的属性Name
吗? - DiskBook 是 Book 的子class,初始化程序
public Book(string name) : base(name)
正在传递引用name
作为最后一个。这里的name
是否也指NameObject中的name
属性?
提前致谢。
从逻辑上讲,很多东西都可以是
NamedObject
。他说Book
是IBook
,也是NamedObject
。想象一下添加一个Person
class。Person
将是NamedObject
,但不是IBook
。因此,您可以重用基础 class 而无需将其绑定到Book
使用
: base(name)
表示call the constructor on the base class with this parameter
。所以你可以确定NamedObject
的构造函数将使用字符串值调用,设置Name
属性。从Book
构造函数中排除: base(name)
将导致编译器错误,因为基础 class 没有无参数构造函数。以同样的方式,
DiskBook
使用: base(name)
调用Book
上的构造函数,后者又调用NamedObject
上的构造函数.