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

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

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

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

 

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

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

 

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

 

posted @ 2018-02-21 02:35  蓝色标记  阅读(288)  评论(0编辑  收藏  举报