相关概念
什么是继承
继承定义了如何根据现有类创先新类的过程
任何类都可以从另外一个类继承
一个派生出来的子类具有这个类的所有公共属性和方法
类的继承机制
创建新类所根据的基础类称为基类或父类,新建的类称为派生类或子类
为什么要继承机制
继承是实现代码重用的重要机制。使用继承可以不需要从头开始创建新类,可以在现有的基础上添加新的方法和属性,节约时间和精力,大大提高效率。
什么是抽象类
不能初始化的类被叫做抽象类,它们只提供部分实现,但是另一个类可以继承它并且能创建它们
的实例(抽象类,不能被初始化,不能被实例化)
用法:一个抽象类只能通过接口和作为其它类的基类使用
一个抽象类必须为所有的接口成员提供实现;一个用于实现接口的抽象类可能把接口方法安排到抽象方法上
抽象类特征
1.抽象类不能被实例化。
2.抽象类可以包含抽象方法和访问器
3.不能把抽象类用密封(sealed)来修饰,那就意味着类不能被继承,这违反抽象类被继承的原则。
4.一个派生于一个抽象类的非抽象类必须包括所有的继承来的抽象方法和访问器的实现
5.在方法和属性中使用abstract 关键字意味着包含它们的实现。
什么是抽象成员
1.必须是函数成员,而不能是字段和常量。
- 使用abstract修饰。
- 不能有实现代码块,以分号替代。
- 抽象成员只能在抽象类中声明。
- 抽象成员类型:方法、属性、事件、索引器。
抽象方法的特征
1.一个抽象方法可以看作是一个虚函数。
2.抽象方法的声明只能在抽象类中。
3.因为抽象方法声明只提供一个无实现的方式,没有方法体
4.方法体的实现被覆写方法提供,覆写方法是一个非抽象类的成员。
5.抽象属性的行为和抽象方法相像,除了不同的声明形式。
6.在一个静态属性中使用abstract 是一个错误。
abstract与virtual对比
- 相同点:都有相同的成员类型,方法、属性、事件和索引器。
- 不同点:
- 修饰符不同;
- 虚方法有实现体,抽象成员没有实现体;
- 在派生类中、虚成员能被覆写,但不是必须的,而抽象成员必须被覆写。
注意事项
抽象属性和抽象方法必须是共有的(public)
子类继承抽象类,需要override抽象类中的抽象属性和抽象方法,如果有未override的,则子类也必须为抽象类
一个抽象类可以包含抽象和非抽象方法,当一个类继承于抽象类,那么这个派生类必须实现所有的基类抽象方法
抽象类的部分实现:通过声明派生类也为抽象,可以避免所有或特定的虚方法的实现
一个抽象类能够继承另一个非抽象类。继承了基类的方法,添加新的抽象和非抽象方法是可行的
什么是多态
同一操作,作用于不同的对象,可以有不同的解释,产生不同的执行结果,这就是多态性
方法重载与多态的区别与联系
在面向对象编程范式中,多态性往往表现为"一个接口,多个功能"。
多态 体现在 重载 和 重写 上
重载是在同一个类中有多个同名不同参数的方法;
重写是在继承类中有与基类同名同参的方法
重载是指具有相同的函数名词,但是参数类型,个数(必须的)与返回值(不是必须的)不相同。
编程题
已知形状类如下:
/// <summary> /// 形状类 /// </summary> public abstract class Shape { /// <summary> /// 计算面积 /// </summary> /// <returns>int</returns> public abstract int ComputeArea(); /// <summary> /// 计算体积 /// </summary> /// <returns>int</returns> public abstract int ComputeVolume(); public int volume; public const double PI = 3.1415926; }
1.设计并实现长方体类,该类的具体的功能如下:
从形状类(Shape)派生;
计算长方体的体积;
计算长方体的表面积;
具有构造函数,可在创建长方体对象时,指定长方体的特征;
长方体的特征包括int 长、int 宽、 int高;
长方体的长宽高均不超过50;
2.设计并实现圆锥类,该类的具体的功能如下:
从形状类(Shape)派生;
计算圆锥体的体积;
计算圆锥体的表面积;
具有构造函数,可在创建圆锥体对象时,指定圆锥体的特征;
长方体的特征包括int 半径、int 高;
长方体的半径和高均不超过50;
解答
创建形状类
根据上面的题目,首先创建形状类Shape.cs
public abstract class Shape { public int volume; public const double PI = 3.1415926; /// <summary> /// 计算面积 /// </summary> /// <returns>int</returns> public abstract int ComputeArea(); /// <summary> /// 计算体积 /// </summary> /// <returns>int</returns> public abstract int ComputeVolume(); }
创建长方体类
Cuboid.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace WindowsFormsApp02_长方体与圆锥类 { class Cuboid : Shape //继承抽象类 { //字段 private int _length; private int _width; private int _height; //属性 public int Length{ get => _length; set => value = value > 50 || value <= 0 ? 50 : value; } public int Width { get => _width;set=>value=value>50|| value <= 0 ? 50 : value; } public int Height { get => _height; set => value = value > 50 || value <= 0 ? 50 : value; } //构造函数 public Cuboid(){} //构造函数-重载 public Cuboid(int length,int width,int height ) { Length = length; Height = height; Width = width; } //实现抽象方法 /// <summary> /// 计算长方体表面积 /// </summary> /// <returns>int型 返回长方体表面积</returns> public override int ComputeArea() { return (Height * Width + Width * Length + Height * Length) * 2; } /// <summary> /// 计算长方体体积 /// </summary> /// <returns>int型 返回长方体体积/returns> public override int ComputeVolume() { return Height * Width * Length; } } }
创建圆锥体类
Cone.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace WindowsFormsApp02_长方体与圆锥类 { class Cone:Shape //继承抽象类 { //字段 private int _radius; private int _height; //属性 public int Radius { get => _radius; set => value = value <= 0 || value > 50 ? 50 : value; } public int Height { get => _height; set => value = value <= 0 || value > 50 ? 50 : value; } //构造函数 public Cone() { } //构造函数-重载 public Cone(int radius, int height) { Radius = radius; Height = height; } //实现抽象方法 /// <summary> /// 计算圆锥表面积 /// </summary> /// <returns>int型,圆锥表面积计算结果</returns> public override int ComputeArea() { return Convert.ToInt32(PI * Radius * Radius + PI * Radius * Math.Sqrt(Height*Height+Radius*Radius)); } /// <summary> /// 计算圆锥体积 /// </summary> /// <returns>int型,圆锥体积计算结果</returns> public override int ComputeVolume() { return Convert.ToInt32((PI * Radius * Radius * Height) / 3); } } }