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

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(里氏替换原则 ,抽象类,接口))