对面向对象三大特征的理解

以Word绘制和组合图形为例:绘制一个矩形,再绘制一个圆
在这里插入图片描述
可以组合它们成为一个整体
在这里插入图片描述
一、封装
所有的事物我们都可以用抽象的类来表示,每一个类又有它的成员:属性和方法,这些成员对其他哪些类可见,对哪些类需要隐藏也属于封装的一部分,如上所述我们可以把一个矩形看成一个类它有长和宽等属性,圆又是一个类,组合后的图形又是一个新的类,也可以把所有都归为一个类-图形类…

 //矩形类
    class Rect
    {
        int x, y;           //左顶点坐标
        int width, heigth;  //长和宽
        public virtual void drawing()
        {
            Console.WriteLine("这是一个左顶点坐标为({0},{1}),长为{2}宽为{3}的矩形", x, y, width, heigth);
        }
    }

    //圆类
    class Circle
    {

        int r;           //半径
        int x, y;        //左顶点坐标

        public virtual void drawing()
        {
            Console.WriteLine("这是一个圆心坐标为({0},{1}),半径为{2}的圆", x, y, r);
        }
    }

二、继承
子类继承父类的所有成员,在此基础上子类可以进一步扩展,添加属于自己的新成员, 继承的部分无需额外编码,特殊地,接口继承仅使用属性和方法的名称,子类必须提供实现功能的代码。

在不使用多态的情况下实现多种图形多个的组合

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace zhy_0718
{
    class Shape
    {
        public int shapeType;
        public void drawing()
        {
           
        }
    }

    //矩形类
    class Rect : Shape
    {
        public int x , y ;           //左顶点坐标
        public int width, heigth;  //长和宽

        public Rect()
        {
            this.shapeType = 1;

            this.x = this.y = 1;
            this.width = this.heigth = 2;
        }
        
        new public void drawing()
        {
            Console.WriteLine("这是一个左顶点坐标为({0},{1}),长为{2}宽为{3}的矩形", x, y, width, heigth);
        }
    }

    //圆类
    class Circle : Shape
    {

        public int r;           //半径
        public int x, y;        //左顶点坐标

        public Circle()
        {
            this.shapeType = 2;

            this.r = 1;
            this.x = this.y = 0;
        }

        new public void drawing()
        {
            Console.WriteLine("这是一个圆心坐标为({0},{1}),半径为{2}的圆", x, y, r);
        }
    }

    //三角形类
    class Triangle : Shape
    {

        public int x1, y1, x2, y2, x3, y3;        //三个顶点的坐标

        public Triangle()
        {
            this.shapeType = 3;

            this.x1 = this.y1 = 0;
            this.x2 = this.y2 = 3;
            this.x3 = 1; this.y3 = 0;
        }
        new public void drawing()
        {
            Console.WriteLine("这是一个由点({0},{1})、({2},{3})和({4},{5})构成的三角形", x1, y1, x2, y2, x3, y3);
        }
    }
    //...所有图形的类

    //组合类
    class Com
    {

        public List<Shape> shapeList=new  List<Shape>();

        public void AddShape(Shape s)
        {
            this.shapeList.Add(s);
        }
        public void drawing()
        {

            Console.WriteLine("开始绘制组合图形");
            for (int i = 0; i < shapeList.Count; i++)
            {
                switch (shapeList[i].shapeType)
                {
                    case 1:
                           ((Rect)shapeList[i]).drawing();break;
                    case 2:
                           ((Circle)shapeList[i]).drawing();break;
                    case 3:
                           ((Triangle)shapeList[i]).drawing();break;
            }

            }


            Console.WriteLine("绘制组合图形结束");
        }

    }
    class Program
    {
        static void Main(string[] args)
        {

            Com com = new Com();
            Rect rect = new Rect();
            com.AddShape(rect);
            Circle cir = new Circle();
            com.AddShape(cir);
            Triangle tri = new Triangle();
            com.AddShape(tri);

            com.drawing();
            
            Console.ReadKey();
        }
    }
    
}

就这样的话,存在一个问题,我的图形有多少种我的case就得有多少个,原因在于我们不能判断父类引用变量指向的子类类型,必须标识再强转,这样代码就要写很多了

三、多态
多态最大的好处就是:允许将子类类型的指针赋值给父类类型的指针。
实现多态,有二种方式:
覆盖,是指子类重新定义父类的虚函数的做法。
重载,是指允许存在多个同名函数,而这些函数的参数表不同

使用多态就简便多了,它能自己识别父类引用变量指向的子类类型不管是什么什么图形,一行代码就解决,及时新增一个新的图形,也无需再修改此方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication_zhy3
{
     interface Shape
    {
         void drawing();
    }

    //矩形类
    class Rect:Shape
    {
        int x, y;           //左顶点坐标
        int width, heigth;  //长和宽
        public virtual void drawing()
        {
            Console.WriteLine("这是一个左顶点坐标为({0},{1}),长为{2}宽为{3}的矩形", x, y, width, heigth);
        }
    }

    //圆类
    class Circle:Shape
    {

        int r;           //半径
        int x, y;        //左顶点坐标

        public virtual void drawing()
        {
            Console.WriteLine("这是一个圆心坐标为({0},{1}),半径为{2}的圆", x, y, r);
        }
    }

    //三角形类
    class Triangle:Shape
    {
        int x1, y1,x2, y2,x3, y3;        //三个顶点的坐标

        public virtual void drawing()
        {
            Console.WriteLine("这是一个由点({0},{1})、({2},{3})和({4},{5})构成的三角形", x1, y1, x2, y2, x3, y3);
        }
    }
    //...添加任意图形的类

    //组合类
    class Com 
    {

        public List<Shape> shapeList = new List<Shape>();

        public void AddShape(Shape s)
        {
            this.shapeList.Add(s);
        }
        public void drawing()
        {

            Console.WriteLine("开始绘制组合图形");
            for (int i = 0; i < shapeList.Count; i++)
                shapeList[i].drawing(); 

            Console.WriteLine("绘制组合图形结束");
        }

    }
    class Program
    {
        static void Main(string[] args)
        {
            Com com= new Com();

            Rect rect0 = new Rect();
            com.AddShape(rect0);
       
            Circle cir0 = new Circle();
            com.AddShape(cir0);

            Triangle tri0 = new Triangle();
            com.AddShape(tri0);

            com.drawing();

            Console.ReadKey();
        }
    }
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值