美文网首页U3D技术采集
OOP(里氏替换原则 ,抽象类,接口)

OOP(里氏替换原则 ,抽象类,接口)

作者: Unity开发 | 来源:发表于2016-12-09 20:16 被阅读214次

    LSP:里氏替换原则

    * 原则上来讲,子类对象可以赋给父类对象,也可以说子类替换父类,并且出现在父类能过出现的任何地方

    *

    * 反过来说,父类对象时不能替换子类对象的,这种特性称为里氏替换原则

    * 1.子类可以隐士的转换为父类对象

    * 2.父类必须强转子类

    *

    * is&&as

    * is :相当于判断,A is B A是不是B或者说A是不是B的子类?

    * as :先判断在转换,(他比传统的强之转换相对安全,因为传统的强值转换,一旦转换失败,程序就崩溃了,)

    *

    * B b;定义栈上的引用变量b,此时是空引用,也就是null 存于栈,用来保存将来引用对象的地址

    * b=new B:通过new关键词创建B类的对象,对象的实例保存在托管堆,CRl在建立实例对象的时候,

    * 还回创建它的类型对象

    * ,对象实例在堆中的内存包括,字段,类型对象指针,同步索引块,类型对象指针指向的是类型对象

    *

    * 类型对象在堆中的内存包括类型对象指针,索引块,静态字段,方法列表

    *

    * A a=new B

    * ;声明一个类型为A的引用类型a,并将其实际地址指向B所指向的那个对象实例

    *

    * a.MethodF();

    * 当调用一个方法的时候,会直接检查这个对象的类型,首先找到堆中的类型对象,查看其是否有该方法,

    * 如果有,直接调用,如果没有,则通过类型对象的类型对象指针向上继续查找,直到找到该方法,

    * 找到该方法之后,他会先检查该方法是否为Virtula,如果非虚直接调用,如果是需方法,既有virtual修饰的关键词

    * 则会引用变量a,去找对象的实例类B,查找该方法是否重写了该虚方法,如果有,执行,没有继续向上查找,直到找到为止

    *

    * 由于MetthodG为需方法既会找到实例B,又由于B重写了MetthodG,所以直接输出

    *

    */什么是抽象方法

    *

    * 抽象类:

    * 在程序中使用关键字abstract

    *

    * 如果说正常类是一个完整类,抽象类实际上是一个不完整的类

    *******************************************************************************************************

    * 抽象类的特点

    * 1.如果类中存在抽象方法,那么该方法不能有实现部分,该方法只能有声名

    * 2.含有抽象方法的类一定是抽象类

    * 3.抽象类不一定含有抽象方法

    * 4.如果子类继承子类的父类为抽象类并且还有抽象方法,子类必须重写父类抽象方法并且实现

    * 5.virtual和abstract不能使用private修饰符,要用public修饰符

    * 6.virtual不能和abstract放在一起

    * 7.抽象类不能被实例化

    * 8.抽象类可以包含静态成员

    *

    * 抽象类的作用:

    * 父类约束子类行为

    **********************************************************************************************

    * 接口:接口就是公共契约

    * 接口的关键字:interface

    * 接口和类属于同级关系,属于C#中的编程单位

    * 接口也被叫纯洁的抽象类

    *

    * 接口特点:

    * 1.不能有字段

    * 2.接口内不能有修饰符

    * 3.接口中不能有方法体(方法实现)

    * 4.接口同样不可以被实例化

    * 5.接口里面成员总是公共的

    * 6.接口中可以有属性但是不能有修饰符

    * 7.接口中可以有索引器/事件声明

    * 8.接口中生命的方法子类实现的时候子类虽然也用override关键字,但是记住不属于重写,这里不能把override显示的声明出来

    *

    * 开发准则:尽量多用接口,能用接口不用抽象类,能用抽象类就不用虚方法

    * 动态多态性

    //里氏替换原则

    class Person           //父类

    {

    public void Say()

    {

    Console.WriteLine ("父类");

    }

    }

    class Zhang:Person        //子类

    {

    public new  void Say()

    {

    Console.WriteLine ("张说");

    }

    }

    class Li:Person

    {

    public  new void Say( )

    {

    Console.WriteLine ("李说");

    }

    }

    class MainClass

    {

    public static void Main (string[] args)

    {

    // Person p = new Zhang ();

    // p.Say ();

    //

    // Person p1 = new Li ();

    // Person p2 = p1;//编译通过

    //

    // Li l1 = p1;//编译不通过,因为父类必须强转子类

    // Li l1 = (Li)p1;

    // Person p=new Zhang();

    // Zhang z = (Zhang)p;

    // //子类和子类

    // Zhang z1=new Zhang();

    // Li l1 = new Li ();

    //

    // z1 = (Zhang)l1;//编译不通过

    Person p1 = new Zhang ();

    if (p1 is Zhang) {

    Zhang z1=p1 as Zhang;

    z1.Say();

    }

    else {

    Console.WriteLine ("______-_-___");

    }

    }

    //抽象类

    //练习:Shap类,表示一个形状的抽象类

    //该类包含一个求圆形面积的抽象方法Area()

    //请从Shap的派生类,梯形,圆形,三角形,菱形实现各自的面积.

    abstract class Shap{

    public abstract void Area();

    }

    class Pai:Shap{

    public int r;

    public Pai(int r)//

    {

    this.r=r;

    }

    public override void Area ()

    {

    double m = r * r * 3.14;

    Console.WriteLine ("圆形的面积为:{0}",m);

    }

    }

    class Sanjiao:Shap

    {

    public int r;

    public int a;

    public override void Area ()

    {

    double m = r*a/2;

    Console.WriteLine ("三角形的面积为:{0}",m);

    }

    }

    class Tixing:Shap

    {

    public int r;

    public int a;

    public int c;

    public Tixing(int r,int a ,int c)

    {

    this.a=a;

    this.c=c;

    this.r=r;

    }

    public override void Area ()

    {

    double m = (r+a)*c/2;

    Console.WriteLine ("梯形的面积为:{0}",m);

    }

    }

    class Linxing:Shap

    {

    public int a;

    public int b;

    public Linxing(int a,int b)

    {

    this.a=a;

    this.b=b;

    }

    public override void Area ()

    {

    int  m = a * b;

    Console.WriteLine ("菱形的面积为:{0}",m);

    }

    }

    class MainClass

    {

    public static void Main (string[] args)

    {

    //new Huang ().Say ();

    //需要计算面积用到的参数,请自己想办法解决.

    Pai p=new Pai(4);

    p.Area ();

    Sanjiao s = new Sanjiao ();

    s.a = 6;

    s.r = 3;

    s.Area ();

    Tixing t = new Tixing (4, 6, 6);

    t.Area ();

    Linxing l = new Linxing (5, 9);

    l.Area ();

    }

    //接口

    interface IInput

    {

    void Read();

    }

    interface IInputTwo

    {

    void Read();

    }

    class Test:IInput,IInputTwo

    {

    public string name;

    //如果接口出现方法同名情况需要以下列方式实现,但是调用的时候

    //要用动态多态性调用,非常规调用方式

    // public void IInput.Read(){

    // Console.WriteLine ("1111");

    // }

    //

    // public void IInputTwo.Read(){

    // Console.WriteLine ("2222");

    // }

    public void Read(){

    Console.WriteLine ("1111");

    }

    // public void Read(){

    // Console.WriteLine ("2222");

    // }

    public IInput T(){

    Test t = new Test ();

    t.name = "测试返回接口实例";

    return t;

    }

    }

    class MainClass

    {

    public static void Main (string[] args)

    {

    // new Test ().Read ();

    //返回接口实例

    Test t = new Test();

    Console.WriteLine (t.name);

    Test t1 = (Test)t.T ();

    Console.WriteLine (t1.name);

    // Test t = new Test ();

    }

    相关文章

      网友评论

        本文标题:OOP(里氏替换原则 ,抽象类,接口)

        本文链接:https://www.haomeiwen.com/subject/otkymttx.html