C#学习笔记 类的继承

类的继承

继承(inheritance)是面向对象程序设计中最为重要的特征之一。C#中不支持多重继承。父类实际上是所有子类的公共字段和公共方法的集合,而每一个子类则是父类的特殊化,是对字段和方法在功能、内涵方法的扩展和延伸。

派生子类

C#中类的继承格式如下:

class SubClass : BaseClass
{
    
    
	......
}

如果缺省冒号及父类名,则该类为object(即System.Object)的子类。因此,在C#中,所有的类都是通过直接或间接地继承object得到的,或者说,所有的类都是object的子类。子类自动地从父类那里继承所有字段、方法、属性、索引器等成员作为自己的成员。除了继承父类的成员外,子类还可以添加新的成员,还可以隐藏或修改父类的成员。

字段的隐藏

子类重新定义一个与从父类那里继承来的字段变量完全相同的变量,称为字段的隐藏。字段的隐藏在实际编程中用得较少。
在C#中,隐藏父类字段时,应该在子类的同名字段的声明前加一个修饰符new,否则,编译器会发出一个警告信息。例:

class A
{
    
    
	public int a;
}
class B : A
{
    
    
	new public int a;	
}

当子类中隐藏了父类的同名字段时,编译器将根据声明的对象变量的类型来决定使用子类的字段量还是父类的字段。


方法的重载、新增与重写

重载: 与同一个类中方法重载的方式一样。

新增: 定义同名且参数列表也与父类相同的方法,这称为新增加一种方法,这种情况下,应在子类的同名方法前面用一个修饰语new,否则编译器会给出警告信息。例如在子类Student中定义同名的new方法:

	new void sayHello(){
    
    
		Console.WriteLine("Hello! My name is " + name + ". My school is " + school);
	}

在子类中已定义的方法用new修饰时,编译器将根据声明的对象变量的类型来决定使用子类的方法还是父类的方法。

  • 新增同名方法会带来理解的困难和歧义,在实际编程中一般不用。

重写:
定义同名且参数列表也与父类相同的方法,而且父类的方法要用virtual进行修饰,子类的同名方法使用override进行了修饰,这称为虚方法的重写(overriding),也叫“覆盖”。在实际编程中,“重写”用得很多,这使得子类可以改写或扩充父类的同名方法。例如:Student类的sayHello() 可以与PersonsayHello() 有不同的表现。这种情况,在C#中称为虚方法调用,它是“多态”的一种表现。虚方法在调用时,会根据实对象实例的具体类型来进行调用。

使用base

C#中除了使用this外,还有一个关键字base。简单地说,base是指父类,base在类的继承中有重要作用。

1. 使用base访问父类的字段和方法

一般情况下,子类可以直接使用父类的属性和方法,也可以使用this来指明本对象(注意,正是由于继承,使用this可以访问父类的字段和方法)。但有时为了明确地指明父类的字段和方法,就要用关键字base。例如:若父类有一个字段age,那么在子类中访问以下三种方法是完全一样的:

	void testThisBase(){
    
    
		int a;
		a = age;
		a = this.age;
		a = base.age;
	}

有时需要使用base以区别同名的字段与方法。如使用base可以访问被子类隐藏了的同名变量。又比如,当覆盖父类的同名方法时,又要调用父类的方法,就必须使用base。例如:

	void sayHello(){
    
    
		base.sayHello();
		Console.WriteLine("My school is " + school);
	}

从这里可以看出,即使同名,也仍然可以使用父类的字段和方法,这也使得在覆盖父类方法的同时,还利用已定义好的父类的方法。

2. 使用父类的构造方法

在严格意义上,构造方法是不能继承的。比如,父类Person有一个构造方法Person(string, int),不能说子类Student也自动有一个构造方法Student(string, int)。但是,这并不意味着子类不能调用父类的构造方法。以下为调用示例:

	Student (string name, int age, string school):base(name, age){
    
    
		this.school = school;
	}

注意: base指的是对象,所以它不能在static环境中使用,包括静态变量(static field)、静态方法(static method)、static构造方法。

父类与子类的转换

  • 子类对象可以被视为是其父类的一个对象
  • 父类对象不能当作是某个子类的对象
	Person p = new Student();	// 正确
	Student s = new Person();	// 错误

属性、索引器的继承

与方法的继承一样,子类也会继承父类的属性和索引器,同时子类也可以增加属性和索引器。子类还可以定义父类同名或同参数列表的属性或索引器。
定义同名属性时,有两种方法:一是在子类中的同名属性用new修饰,表示新建的属性,它隐藏了父类的同名属性;(这种情况实际编程很少使用);二是在父类的属性用virtual进行修饰,子类的同名属性用override进行了修饰,这称为属性的重写(overriding)。
使用索引器也是与属性类似,两种方法。

猜你喜欢

转载自blog.csdn.net/qq_45349225/article/details/113894520