继承
经常会需要扩展现有的类型来添加方法或数据。比如我们首先有一个Student类来存储学生的姓名、年龄等信息,现在需要建立一个类BoyStudent来存储男同学的兴趣爱好。因为每个男同学都是学生,因此Students类中的所有内容都应该被包含在BoyStudent类;另一方面,BoyStudent类中还包含Student类中不包含的内容,如兴趣的种类。在这种情况下,BoyStudent类就可以在Student类的基础上建立,即在Student类的基础上添加新的内容。我们可以称BoyStudent类继承自Student类,其中Student类称为基类,BoyStudent称为派生类。
来看两段代码。
//基类
public class Student
{
public string Name{get;set}
private int Age{get;set}
public virtual string Teacher{get;set}//允许重写的属性
}
// 派生类
public class BoyStudent : Student
{
public string Hobby{get;set}
public string TeacherName;
public override string Teacher
{
get
{
return $"Dear {TeacherName}";
}
set
{
TeacherName = value;
}
}
}
// 调用
public class Program
{
public static void Main()
{
BoyStudent boyStudentTom = new BoyStiudent();
boyStudent1.Name = "Tom";
Student studentTom = boyStudentTom;// 类型转换
}
}
- 继承的标识符是":","A:B"表示类A继承自类B。
- C#的类是单继承的,这意味着":"后面只能写一个类。
- 如调用中的函数所示,虽然没有在BoyStudent类中定义Name属性,但是在它的基类Student中有public的Name属性,因此可以直接进行访问,或者说,每个派生类继承除构造函数和析构器之外的所有基类成员。但是继承不意味着可以访问,Student类中的Age属性,被限定为private,它不可以在派生类中进行访问。除了public和private这两个极端的修饰,还有一个折中的修饰符protected,它意味着改成员只有基类及其派生类可以访问。
- 派生类可以转换成基类,调用中转换的代码是隐式转换,也可以使用显式转换。但是注意,派生类向基类转换是可以的,但是基类向派生类转换不可以。因为派生类一定属于基类,但是基类不一定属于派生类。
- 如果基类中的某些成员不太满足派生类的要求,可以在派生类中重写。但是C#只支持重写实例方法和属性,不支持字段和任何静态成员的重写。此外,必须在基类中将每个允许重写的成员都用virtual修饰符修饰,在派生类重写时,要加上override修饰符。
- 如果不希望被重写,可以对成员加上sealed修饰符修饰。
- 所有的类直接或间接从object派生。
- 有一种类是抽象类,其抽象成员定义了从抽象实体派生的对象应包含什么,但这种成员不包含实现。抽象类的大多数功能通常都没有实现。一个类要从抽象类成功地派生,必须为抽象基类中的抽象方法提供具体的实现。抽象类需要在类前加abstract修饰符修饰。
接口
接口有点像协议,在其中定义实现的某些功能的方法名称和这些方法需要的参数类型。这样的话,该接口的所有派生类的实例,在调用该方法时就会有统一的格式。
// 定义接口
interface IfileWrite
{
void FileWrite(string address,string fileName);
}
- 接口用interface关键字声明,按照约定,接口的名称最好加一个I前缀。
- 接口不包含实现和数据,在接口中不能出现字段,但是可以包含属性,属性不能引用支持字段,接口中也不能拥有静态成员。
- C#不允许为接口成员使用访问修饰符,所有成员自动公共。
- 接口永远不能实例化,接口不含有构造函数和终结器。
// 接口派生类
class Example:IfileWrite
{
public void FileWrite(string address,string fileName)
{
...//具体实现
}
}
- 声明类来实现接口类似于从基类派生——要实现的接口和基类名称以逗号分隔(基类在前,接口顺序任意)。类可实现多个接口,但只能从一个基类直接派生。
- 实现接口时,接口的所有成员都必须实现。实现方式有显式实现和隐式实现两种,上文的例子是隐式实现。
- 一个接口可以从另一个或多个接口派生,派生的接口将继承“基接口”的所有成员。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。