文章目录
- 一、继承的基本使用
- 继承的概念:
- 继承的特点:
- 为什么使用继承?
- 二、继承的关键字
- 1、this关键字
- 2、base关键字
- 3、Protected关键字
- 4、子类调用父类的构造函数的总结:
- 三、继承的特性
- 继承的传递性:
- 继承的单根性:
- 四、深入理解多态
- 五、多态的实现和应用
- 使用继承实现多态
- 继承多态在方法调用方面的应用
- 六、里氏替换原则
面向对象编程(OOP)有三个主要特性:
-
封装(Encapsulation):
封装是将数据(属性)和操作数据的方法(函数)绑定在一起,并隐藏内部实现细节的特性。通过封装,可以将对象的内部状态保护起来,只允许通过对象提供的公共接口进行操作,从而提高代码的安全性和可维护性。 -
继承(Inheritance):
继承允许一个类(子类)继承另一个类(父类)的属性和方法,从而实现代码的重用。子类可以扩展或修改父类的行为,形成一个层次结构。通过继承,可以简化代码并增加系统的可扩展性。 -
多态(Polymorphism):
多态指的是不同的对象对相同的消息(方法调用)做出不同的响应。它允许一个接口以多种形式出现。例如,同一个方法名称在不同的对象中可以有不同的实现。多态提高了系统的灵活性和扩展性。
这三个特性是面向对象编程的核心,帮助开发者设计更为模块化、易维护和可扩展的软件系统。
一、继承的基本使用
继承的概念:
允许一个类(子类)继承另一个类(父类)的属性和方法,从而实现代码的重用。
继承的特点:
继承的顺序不可逆,继承的下级拥有上一级的属性和方法。
为什么使用继承?
解答:最主要的方法是实现代码的复用,举例:有一个猫类和狗类,但是两者都有大量的属性和方法是重复的,所以这个时候可以建一个动物类,让猫类和狗类继承动物类,减少代码的使用。
应继承的步骤和使用要点:
- 1、抽象的公共部分放到一个特定的类中(父类)
- 2、其他子类继承父类,就能拥有父类的属性和方法。
- 3、根据子类的需要,写单独的特征和方法。
具体实现方法:
在子类的后面使用冒号:父类
class Dog : Animal
{
//赛跑
public void Race()
{
Console.WriteLine("下面我给大家表演《狗狗精彩百米跨栏》,请大家鼓掌啊:>");
}
}
二、继承的关键字
1、this关键字
this关键字可以访问父类的成员。this: 用于访问当前类的成员。你可以用 this 来引用当前对象的字段、属性和方法。它主要用于明确指示你是在引用当前对象的成员,有助于解决命名冲突(例如,构造函数的参数名与字段名相同的情况)
public class Parent
{
public int Value;
public void PrintValue()
{
Console.WriteLine(this.Value);
}
}
base: 用于访问基类(父类)的成员。它允许你在派生类中访问基类中的字段、属性和方法,特别是在重写方法时。base 主要用于访问或调用基类中被隐藏或重写的成员。
public class Parent
{
public int Value;
public void PrintValue()
{
Console.WriteLine(Value);
}
}
public class Child : Parent
{
public new int Value; // 在子类中隐藏父类的 Value 字段
public void PrintParentValue()
{
Console.WriteLine(base.Value); // 访问父类中的 Value 字段
}
}
2、base关键字
调用父类的构造函数、调用父类的属性和方法。base
关键字可以在方法,构造函数和属性的访问器中使用,但是不可以在结构、成员声名中使用。
错误的使用:
class Dog : Animal
{
public Dog(string name, string color, string kind, string favorite)
: base(name, color, kind)//调用父类的构造方法
{
this.Favorite = favorite;
}
base.Introduce();//在成员声名中使用是无效的
}
正确的使用:
父类:
class Animal
{
//无参数构造函数
public Animal() { }
//3个参数的构造方法
public Animal(string name, string color, string kind)
{
this.Color = color;
this.Name = name;
this.Kind = kind;
}
public string Name { get; set; }//名字
public string Color { get; set; }//颜色
public string Kind { get; set; }//种类
public string Favorite { get; set; }//喜好
//自我介绍
public void Introduce()
{
string info = string.Format("我是漂亮的{0},我的名字叫{1},身穿{2}的衣服,我爱吃{3}!", Kind, Name, Color, Favorite);
Console.WriteLine(info);
}
}
子类:
class Dog : Animal
{
public Dog(string name, string color, string kind, string favorite)
: base(name, color, kind)//调用父类的构造函数
{
this.Favorite = favorite;
}
//赛跑
public void Race()
{
base.Introduce();//调用父类的方法
Console.WriteLine("下面我给大家表演《狗狗精彩百米跨栏》,请大家鼓掌啊:>");
}
}
如上使用this也可以,但是最好要用base,更好阅读性,base先调用父类的构造函数,然后再调用子类的构造函数,因为创建子类实例的时候会先创建子类所继承的父类。
3、Protected关键字
如果父类中的某个成员函数只允许其子类访问,那么使用Protected关键字
// 定义子类 Dog 继承自 Animal
public class Dog : Animal
{
// 子类构造函数
public Dog(string name) : base(name)
{
}
// 子类的方法,用于调用父类的 protected 方法
public void DogSpeak()
{
// 可以直接访问父类的 protected 成员
Speak();
}
}
4、子类调用父类的构造函数的总结:
问题:如果去掉父类的构造函数,并且子类不使用base那么会如何?
隐式调用:如果其他子类的构造函数没有使用base指明调用的父类的那个构造函数时,子类会默认调用父类的无参数构造函数。
显示调用:如果父类没有无参数的构造函数,子类的构造函数必须指明调用父类的那个构造函数。
总之父类要么写一个无参数的默认的构造函数,要么子类指定,不然会报错。
三、继承的特性
继承的传递性:
A是B的父类,B是C的父类,那么C具有A的特性。
继承的单根性:
一个类只能有一个父类。
四、深入理解多态
多态的概念:不同的对象,接收相同的消息,产生不同的行为,称为多态。
多态是由虚拟机自行决定的。
五、多态的实现和应用
使用继承实现多态
- 父类中必须有抽象方法或虚方法(虚方法后面讲述)。
- 子类必须重写父类中的抽象方法或虚方法。
- 子类对象必须转换成父类类型去使用。
继承多态在方法调用方面的应用
粗浅的理解:父类类型作为方法参数,子类调用传递过来子类对象,子类被转换成父类类型,提高了代码的维护性和合作性。