C#笔记进阶篇01 类的继承
——本系列是基于人民邮电出版社《C#2008 C#图解教程》、清华大学出版社《C#入门经典(第五版)》两本书的自学C#笔记,如果您发现了本文的纰漏,还望不吝指正。
写在前边:
封装、继承、多态,是面向对象的三大特性。所以继承是面向对象程序设计中最重要的概念之一
1. 基类和派生类
任何类都可以从另一个类中继承,这就是说,这个类拥有它继承的类的所有成员。在OOP(Object-Oriented Programming,即面向对象编程)中,被继承(也称为派生)的类称为父类(也称为基类)。注意,C#中的对象仅能直接派生于一个基类,当然基类也可以有自己的基类。——清华大学出版社《C#入门经典(第五版)》
用一个已存在的类去定义出一个新的类
-
新的类叫做 子类/派生类
-
已存在的类叫做 父类/基类/超类
声明方法:访问修饰 class 派生类名:基类名{ }
例:创建一个Person类,一个Studunt类派生自Person
class Person
{
public string name;
public int age;
public char sex;
public Person(string name, int age, char sex)
{
this.name = name;
this.age = age;
this.sex = sex;
}
public void SayHallo()
{
Console.WriteLine("大家好,我是{0},今年{1},性别{2}",name,age,sex);
}
}
class Student : Person
{
public string major;
//子类的构造函数中需要继承的参数需要使用base关键字
public Student(string name, int age, char sex, string major): base(name,age,sex)
{
this.major = major;
}
public new void SayHallo()
{
base.SayHallo();
Console.WriteLine("我的专业是:"+major);
}
}
2. Object类
除了特殊的Object类,所有的类都是派生类,即使它们没有基类规格说明。
C#中所有类的最终基类都是Object类,如下图所示
3. 派生类的访问
派生类中继承而来的成员可以被访问,就像它们是派生类自己声明的一样。
例:下面的代码声明类SomeClass和它的派生类OtherClass
class SomeClass
{
public string Field1 ="base class field";
public void Method1(string value)
{
Console.WriteLine("Base class --Method1:{0}",value);
}
}
class OtherClass:SomeClass
{
public string Field2 ="derived class field";
public void Method2(string value)
{
Console.WriteLine("Derived class --Method2:{0}",value);
}
}
class Program
{
static void Main()
{
OtherClass oc = new OtherClass();
oc.Method1(oc.Field1);
oc.Method1(oc.Field2);
oc.Method2(oc.Field1);
oc.Method2(oc.Field2);
}
}
控制台输出结果:
————————————————————————————————————————————————————
Base class – Methood1:base class field
Base class – Methood1:derived class field
Derived class – Methood2:base class field
Derived class – Methood2:derived class field
4. 使用new关键字掩盖基类的成员
如果子类中有成员与父类中的成员重名,可以用new关键字为子类中这个成员申请一个新的空间,以便于计算机识别,(如果不写,也将默认掩盖基类,只是编辑器会有警告)
例:下边的代码中,派生类OtherClass使用new关键字掩盖基类的成员
class SomeClass
{
public string Field1 ="base class field";
public void Method1(string value)
{
Console.WriteLine("Base class --Method1:{0}",value);
}
}
class OtherClass:SomeClass
{
new public string Field1 ="other class field1";
new public void Method1(string value)
{
Console.WriteLine("Other class --Method1:{0}",value);
}
}
class Program
{
static void Main()
{
OtherClass oc = new OtherClass();
oc.Method1(oc.Field1);
}
}
控制台输出结果:
————————————————————————————————————————————————————
Other class --Method1:other class field1
5. 使用base关键字访问基类
在上边的例子中,派生类OtherClass使用new关键字掩盖了基类的变量成员Field1和函数成员Method1(string value),可以使用基类访问表达式来访问基类中被隐藏的成员。
- 基类访问表达式:base.成员名称
在上边的代码中,在派生类中增加代码
class OtherClass:SomeClass
{
new public string Field1 ="other class field1";
new public void Method1(string value)
{
Console.WriteLine("Other class --Method1:{0}",value);
Console.WriteLine(base.Field1);
base.Method1(base.Field1);
}
}
控制台输出结果:
————————————————————————————————————————————————————
Other class --Method1:other class field1
base class field
Base class --Method1:base class field
6. 继承的特性
1).一个类只可以直接继承于一个基类
2).派生类拥有基类的所有属性和方法
3).派生类不能访问基类的私有成员,但可以访问其公共成员
4).子类会默认调用父类的默认构造函数
5).如果父类的默认构造函数失效,子类需要重新指定(使用base关键字)
6).如果一个类没有父类,将默认继承Object类
7).类和结构体的默认访问修饰符:internal 本程序集
8).只有派生类才能访问protected 成员,外部代码不能访问。
扩展:里氏替换原则
SOLID,面向对象设计的五个基本原则:单一功能原则、开闭原则、里氏替换原则、接口隔离原则以及依赖倒置原则
子类可以扩展父类的功能,但不能改变父类原有的功能。它包含以下4层含义:
- 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
- 子类中可以增加自己特有的方法。
- 当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
- 当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。
作者:侠客8090
链接:https://www.jianshu.com/p/93259a886427
来源:简书
将子类当作父类去使用(因为子类拿到了父类的所有内容)或是将父类对象显示转换为子类对象使用
使用is/as关键字,在基类,派生类之间进行尝试转换:
- is:判断这个变量是否能转换成对应类型,如果可以,返回true,否则返回false;
- as: 尝试转换,如果能,返回转换过后的对象,如果不能,返回null
例:接文章最开始的代码,创建一个Person类,一个Studunt类派生自Person
static void Main()
{
Person wangwu = new Student("王五", 20, '男', "C#");
wangwu.SayHallo(); //以人类对象的身份做自我介绍
Person zhangsan = new Person("张三", 18, '男');
zhangsan.SayHallo();
//里式替换
if (wangwu is Student)
{
(wangwu as Student).SayHallo(); //以学生对象的身份做自我介绍
}
if (zhangsan is Student) //尝试转换失败,返回null
{
(zhangsan as Student).SayHallo();
}
}
控制台输出结果:
————————————————————————————————————————————————————
大家好,我是王五,今年20,性别男
大家好,我是张三,今年18,性别男
大家好,我是王五,今年20,性别男
我的专业是:C#