• C#基础(2)


    摘要:面向对象编程是很多编程语言的一种重要思想。万物皆对象。有很多种不同个人理解,其实,用的多了,也就能够去体会和领悟这种思想。个人理解:一个类或者接口, 就是对象,面向对象就是对类或者接口的操作,例如用到一个非静态类,需要先new一个这个类的对象,继承接口需要实现接口中的方法等。  此篇博客主要涉及到之前学习面向对象时的一些代码笔记以及总结。

    涉及内容:   1、里氏替换原则               2、多态之虚方法              3、多态之抽象类             4、工厂设计模式            5、接口

    ----------------------------------------------------------------------------------------------------------------------------

    面对对象(三大特征,五大原则):

    三大特征:封装、继承、多态

    五大原则:

    单一原则: 一个对象应该只包含一个单一的职责,并且该职责被完整的封装在一个类中。如果一个类中封装了过多的职责,这些职责在并发执行的时候回相互干扰

    开放封闭原则: 对扩展开放,对修改代码封闭(主要考虑安全性)

    依赖倒转原则: 高层(heigh leve1)模块不该直接依赖低层(low leve1)模块。它们两个应该依赖抽象

    里氏替换原则: 子类能够替换它们的父类

    接口隔离原则: 客户端不应该依赖那些它不需要的接口

    -------------------------------------------------------------------------------------------------------------------------------

    封装:封装类,封装成方法       --解决代码冗余

    继承:子类继承父类         

       

    1、里氏替换原则

    a、子类可以赋值给父类

          如果有一个方法需要一个父类作为参数,我们可以传第一个子类对象 ,例如:需要一个object类型作为参数,可以传递任何类型的参数 (任何子类都继承object)


    b、如果父类中装的是子类对象,则可以将这个父类强转为子类对象

    2、多态之虚方法

    面向对象多态优点:①解决代码冗余          ▲②:屏蔽各个子类之间的差异,写出通用的代码,适用于每个子类的调用

    虚方法的使用:

    //父类
    public class Person
    {
    public string Name { get; set; }public Person(string name) { this.Name = name;
    }
    public virtual void SayHello() { Console.WriteLine("我是人类"); } //子类① public class Chinese:Person { public Chinese(string name) : base(name) { } public override void SayHello() { Console.WriteLine("我是中国人,我叫{0}",this.Name); }
    }
    //子类② public class America:Person { public America(string name) : base(name) { } public override void SayHello() { Console.WriteLine("我是美国人,我叫{0}",this.Name); } } //调用实例: Chinese ch = new Chinese("张三"); America a1 = new America("乔布斯"); Person[] per = { ch,a1 }; for (int i = 0; i < per.Length; i++) { per[i].SayHello();
    }
    //结果: 两个子类的SayHello方法

     以上实例:将父类的方法标记为虚方法,使用关键字virtual,这个方法可以被子类重新写一遍。

     在父类的方法前面加上一个virtual,在子类的方法前面加上一个override;如果子类的方法前面不加override,编译器不会报错,但这样的话,就无法通过父类来调用子类的方法,因为这个方法成了子类的独有的方法,只是名字与父类相同而已,与父类无关。通过父类调用子类的方法,屏蔽子类之间的差异

     

    3、多态之抽象类:(常用:工厂设计模式)

    问题:运用多态求一个圆与矩形的面积        思考:圆的面积和矩形面积的求法不一样,如何通过写一个父类,然后调用父类的方法,屏蔽子类间的差异?父类根本无法构造方法体

    //父类: 
      public abstract class Graph
     {
         public abstract double Getarea();       //抽象类没有方法实体
      }
    
    //子类①:圆
     public class Circle : Graph
     {
        public double R { get; set; }
        public Circle(double r)
        {  this.R = r;  }
        public override double Getarea()
        {
          return Math.PI * R * R;
        }
      }
    //子类②:矩形
    public class Rectangle : Graph
    {
      public double Hight { get; set; }
    
      public double Width { get; set; }
    
      public Rectangle(double width, double hight)
      {
       this.Width = width;
       this.Hight = hight;
      }
      public override double Getarea()
      {
        return Width * Hight;
       }
    }
    
    //调用实例:
    Graph gh = new Circle(3)
    double circlearea= gh.Getarea();        //求圆的面积
    Graph gh2 = new Rectangle(2, 4.2);
    double rearea = gh2.Getarea();            //求矩形面积

     抽象类的特点:

     a、抽象类中的抽象成员必须标记为abstract,并且不能有任何实现。方法不能有任何实现是指,方法没有大括号,也没有方法体。  只有大括号,没有方法体的方法叫做空实现。

     b、抽象成员必须标记在抽象类中

     c、抽象类是有构造函数的,但抽象类不能被实例化

     d、子类继承抽象类后,必须把父类中的所有抽象成员都重写。(除非子类也是一个抽象类,则可以不重写)

     e、在抽象类中可以包含实例成员,并且它们可以不被子类实现

    以上实例说明:不知道如何去写父类这个方法,通过new子类实现抽象方法,屏蔽子类间的差异。上面简单用下抽象类,常用于:工厂设计模式

     

    4、工厂设计模式:

    参与者:Product:抽象产品类,将具体产品类的公共代码抽象和提取后封装在一个抽象产品类中(抽象类的抽象方法)

                Concerteproduct:具体产品类,将需要创建的各种不同产品对象的相关代码封装到具体产品类中      (继承抽象类的子类的各自方法)

                Factory:工厂类,提供一个工厂类创建各种产品,在工厂类中提供一个创建产品的方法,该方法可以根据传入的参数不同创建不同的产品对象

                Client: 客户端类,只需要调用工厂类的工厂方法,传入相应的方法即可获得产品对象(实现)

     

    5、接口:

    特点:a、接口是一种规范  只要一个类继承了一个接口,这个类必须实现接口的所有成员

               b、接口不能被实例化 也就是说不能创建对象

               c、接口与接口之间可以继承  并且可以多继承,接口不能继承一个类

               d、接口中的成员不能加访问修饰符   默认为public

    接口作用很大:首先实现了多继承,另外常用:不同层之间通过调用接口提高安全性(例:业务逻辑层调用数据会话层的接口)。

             实现 发布订阅模式(观察者模式):我们作为订阅者不必每次都去查看这个公众号有没有新文章发布, 公众号作为发布者会在合适时间通知我们(继承接口)

                                                          我们与公众号之间不再强耦合在一起。公众号不关心谁订阅了它,不管你是男是女还是宠物狗,它只需要定时向所有订阅者发布消息即可(遍历订阅者)

    总结:什么时候用虚方法来实现多态?什么时候用抽象类来实现多态?什么时候用接口来实现多态?

    在我提供给你的几个类当中,如果说你能抽象出来一个父类,并且这个父类必须写上这几个子类共有的方法,然后你还不知道怎么去写这个方法,就用抽象类来写这个多态
    反之,抽象出来的父类,方法可以写,并且我还要创建这个父类的对象,就用虚方法
    这几个类里面根本就找不出来父类,但它们都有一个共同的行为,共同的能力。这个时候就用接口来实现多态

    面向对象多态确实是一个很抽象的东西,具体运用可以根据需求,根据业务逻辑去选择使用。

     

  • 相关阅读:
    NYOJ 527 AC_mm玩dota
    程序员励志小说链接
    android——ListView功能的实现
    调用系统工具
    HDU SPFA算法 Invitation Cards
    nginx sendfile tcp_nopush tcp_nodelay参数解释
    结构体中使用#define定义宏
    HRPlugin For Xcode发布(附源码地址)
    Derby的下载安装和使用,(和JAVA中使用Derby)
    UNIX环境高级编程——进程管理和通信(总结)
  • 原文地址:https://www.cnblogs.com/xsh-cs/p/8456177.html
Copyright © 2020-2023  润新知