用一个简单示例来说明C#中的继承、封装和多态
2012-01-06 18:50
706 查看
下面先来叙述一下问题的描述:要求设计一个能描述所有图形公共属性和方法的的类(Shape),然后设计若干个不同的继承Shape的子类,比如三角形、圆形,矩形等等,基本功能要求:能提供面积和周长的计算和输出
接着我们就来用C#语言的封装和继承的特性分析一下这个类和子类的设计吧,首先就是父类的设计,想一想父类应该包含哪些属性,或者方法呢,对于每个图形我们知道他们都有自己的周长和面积,因此我们可以将其周长和面积放到父类Shape中即可,对于所有具体的某种图形都应该有计算和输出其周长和面积的方法,那计算和输出的方法应该放到子类中呢还是父类中去呢,我们可以从其变化的角度来分析,对于不同图形来说,它们周长和面积的计算公式是不一样的,因此我们可以这样设计,在父类中只是声明计算周长和面积的抽象方法,然后在其子类中去具体的实现即可,再来考虑输出周长和面积的方法应该放到哪儿呢,是子类还是父类呢?在此我是这样设计的,将输出周长和面积的方法在父类中设计成共有虚拟的(即用public
virtual修饰的),这样做的好处是,子类的如果不去重写父类的输出方法,则默认调用父类的输出周长和面积的函数,若是子类对输出周长和面积的格式有一定的变化或者改进的话,子类就完全可以重写(overide)周长和面积输出方法,以满足子类的需要,当重写之后子类就会调用其重写后的方法,即使是转换成父类对象也是调用子类的重写的方法(这就是多态性的体现),好了分析就到这里吧;下面看看具体的代码实现:
在父类Shape代码实现如下:
注:Shape类设计成抽象的,是因为它应该是所有形状的基类;只能作为某种具体形状的父类,不能被实例化
下面简单设计了一下子类圆和三角形类的实现:
圆类代码实现如下:
三角形类代码实现如下:
测试调用代码:
本篇博客只是我学习的理解和认识,希望对于刚学C#语言的朋友们理解继承、封装和多态有一定的帮助作用吧 ,有不对之处还望指正!
接着我们就来用C#语言的封装和继承的特性分析一下这个类和子类的设计吧,首先就是父类的设计,想一想父类应该包含哪些属性,或者方法呢,对于每个图形我们知道他们都有自己的周长和面积,因此我们可以将其周长和面积放到父类Shape中即可,对于所有具体的某种图形都应该有计算和输出其周长和面积的方法,那计算和输出的方法应该放到子类中呢还是父类中去呢,我们可以从其变化的角度来分析,对于不同图形来说,它们周长和面积的计算公式是不一样的,因此我们可以这样设计,在父类中只是声明计算周长和面积的抽象方法,然后在其子类中去具体的实现即可,再来考虑输出周长和面积的方法应该放到哪儿呢,是子类还是父类呢?在此我是这样设计的,将输出周长和面积的方法在父类中设计成共有虚拟的(即用public
virtual修饰的),这样做的好处是,子类的如果不去重写父类的输出方法,则默认调用父类的输出周长和面积的函数,若是子类对输出周长和面积的格式有一定的变化或者改进的话,子类就完全可以重写(overide)周长和面积输出方法,以满足子类的需要,当重写之后子类就会调用其重写后的方法,即使是转换成父类对象也是调用子类的重写的方法(这就是多态性的体现),好了分析就到这里吧;下面看看具体的代码实现:
在父类Shape代码实现如下:
/// <summary> /// 所有图形形状的基类 /// </summary> public abstract class Shape { private double _perimeter; private double _area; private string _shapename; /// <summary> /// 周长 /// </summary> protected double Perimeter { get { return _perimeter; } set { _perimeter = value;} } /// <summary> /// 面积 /// </summary> protected double Area { get { return _area; } set { _area = value;} } /// <summary> /// 形状的名称 /// </summary> protected string ShapeName { get { return _shapename; } set { _shapename = value; } } /// <summary> /// 默认构造函数 /// </summary> protected Shape() { _perimeter=0; _area=0; _shapename=""; } /// <summary> /// 输出周长 /// </summary> public virtual void PrintPerimeter() { Console.WriteLine(ShapeName + "的周长为:"+this.CalculatePerimeter()); } /// <summary> /// 输出面积 /// </summary> public virtual void PrintArea() { Console.WriteLine(ShapeName + "的面积为:"+this.CalculateArea()); } /// <summary> /// 计算周长(因该方法为抽象方法,因此必须在子类中进行重写) /// </summary> /// <returns></returns> public abstract double CalculatePerimeter(); /// <summary> /// 计算面积(因该方法为抽象方法,因此必须在子类中进行重写) /// </summary> /// <returns></returns> public abstract double CalculateArea(); }
注:Shape类设计成抽象的,是因为它应该是所有形状的基类;只能作为某种具体形状的父类,不能被实例化
下面简单设计了一下子类圆和三角形类的实现:
圆类代码实现如下:
/// <summary> /// 圆形 /// </summary> public class Circle : Shape { const double PI=3.1415; private double _r = 0; /// <summary> /// 圆的半径 /// </summary> public double R { get { return _r; } set { _r = value; } } /// <summary> /// 默认构造函数 /// </summary> public Circle(): base() { this.ShapeName ="圆"; } public Circle(double r):this() { this.R = r; } /// <summary> /// 设置半径 /// </summary> /// <param name="r"></param> public void SetRadius(double r) { this.R = r; } /// <summary> /// 计算周长 /// </summary> /// <returns></returns> public override double CalculatePerimeter() { Perimeter = 2 * PI * R; return Perimeter; } /// <summary> /// 计算面积 /// </summary> /// <returns></returns> public override double CalculateArea() { Area = PI * R * R; return Area; } /// <summary> /// 重写父类虚拟的PrintArea方法输出面积 /// </summary> public override void PrintArea() { Console.WriteLine("执行Circle.PrintArea()方法输出面积"); base.PrintArea(); } /// <summary> /// 重写父类虚拟的PrintPerimeter方法 输出周长 /// </summary> public override void PrintPerimeter() { Console.WriteLine("执行Circle.PrintPerimeter()方法输出周长"); base.PrintPerimeter(); } }
三角形类代码实现如下:
/// <summary> /// 三角形 /// </summary> public class Triangle:Shape { //私有字段 private double _a; private double _b; private double _c; #region 属性成员 public double A { get { return _a; } } public double B { get { return _b; } } public double C { get { return _c; } } #endregion /// <summary> /// 继承基类默认构造函数 /// </summary> public Triangle():base() { this.ShapeName="三角形"; } /// <summary> /// 构造函数(需传入三角形的三个边长) /// </summary> /// <param name="a">第一个边</param> /// <param name="b">第二个边</param> /// <param name="c">第三个边</param> public Triangle(double a, double b, double c):this() { if (this.CheckSide(a, b, c) == true) { this._a = a; this._b = b; this._c = c; } } /// <summary> /// 设置三个边的长度 /// </summary> /// <param name="a">第一个边</param> /// <param name="b">第二个边</param> /// <param name="c">第三个边</param> public void SetThreeSideLength(double a, double b, double c) { if (this.CheckSide(a, b, c) == true) { this._a = a; this._b = b; this._c = c; } } /// <summary> /// 检查边长 /// </summary> /// <param name="a">第一个边</param> /// <param name="b">第二个边</param> /// <param name="c">第三个边</param> /// <returns></returns> public bool CheckSide(double a, double b, double c) { if (a > 0 && b > 0 && c > 0) { if ((((a + b) > c && (a + c) > b && (b + c) > a) && (Math.Abs(a - b) < c && Math.Abs(a - c) < b && Math.Abs(b - c) < a))) { return true; } else { throw new ArgumentException("您输入的三个边长不能构成有效的三角形,请检查其边长!"); } } else { throw new ArgumentException("三个边长必须大于0!"); } } /// <summary> /// 计算周长 /// </summary> public override double CalculatePerimeter() { this.Perimeter = A + B + C; return Perimeter; } /// <summary> /// 计算面积 /// </summary> public override double CalculateArea() { //已知三个边面积计算公式:S△=√〔p(p-a)(p-b)(p-c)〕 〔p=1/2(a+b+c)〕(海伦—秦九韶公式) double P= (A + B + C) / 2; Area = Math.Sqrt(P * (P - A) * (P - B) * (P - C)); return Area; } }
测试调用代码:
//Shape triangle = new Triangle(3,4,5); //triangle.PrintArea(); //triangle.PrintPerimeter(); //Shape circle = new Circle(10); //circle.PrintArea(); //circle.PrintPerimeter(); //Console.ReadKey(); Shape[] shapes = new Shape[] { new Circle(10), new Circle(8), new Circle(100), new Triangle(3,4,5), new Triangle(10,10,10), new Triangle(8,10,12) }; foreach (Shape shape in shapes) { Console.WriteLine("***********************************"); shape.PrintArea(); shape.PrintPerimeter(); Console.WriteLine("***********************************"); Console.WriteLine(); } Console.ReadKey();
本篇博客只是我学习的理解和认识,希望对于刚学C#语言的朋友们理解继承、封装和多态有一定的帮助作用吧 ,有不对之处还望指正!
相关文章推荐
- 用一个简单示例来说明C#中的继承、封装和多态
- 关于C#面向对象三个特征:继承,封装,多态的说明
- 关于C#面向对象三个特征:继承,封装,多态的说明
- C#多重继承 + 多态 + 扩展方法 简单示例
- 关于C#面向对象三个特征:继承,封装,多态的说明
- C# 面向对象编程之封装、继承、多态 <思维导图>
- C# 继承,封装和多态
- 封装,继承,多态的类图示例
- C# OOP模型(传说中的继承封装多态)
- JAVA的三大特征 封装继承多态- 简单总结
- C# 简单封装一个XML文件读取类
- RUBY的类封装,继承,多态简单演示
- unity->C#简单的封装+继承
- C# 面向对象特性 封装 继承 多态
- C#的封装、继承和多态
- 【C#学习】——封装、继承、多态
- C# 学习历程——类的封装,继承与多态
- C#学习第四弹之封装、继承和多态
- c# 封装 继承 多态
- 一个关于封装、继承、多态的问题