一、 里氏替换原则–类型转换

1、 里氏替换原则:当需要一个父类类型对象的时候,可以给一个子类类型的对象。

2、 里氏替换原则实际也就是发生了隐身转换

3、  a.>把子类类型赋值给父类类型,发生了隐式类型。

b> 把父类类型变量赋值给子类类型,需要显式类型转换。

C>前提是如果这个父类类型变量p中,指向的确实是一个子类对象,则可以显式类型转换,如果p指向的不是子类的对象,则显式转换会报异常。(转换失败)    is-a可以用来验证继承关系中是否合理

4、 =======================as===================

//如果转换成功则将结果赋值给cn变量,

//如果转换失败也不报错,会将null值赋值给cn;

//最好在转换后,加一个cn是否为null的验证。

Chinese cn = per as Chinese;

if (cn!=null)

            {

//做一些事情

            }

//如果转换失败会报错!!!

Chinese cn1 = (Chinese)per;

============================================================================

/// <summary>

/// 父类类型作为参数的一种多态

/// </summary>

/// <param name=”per”></param>

static void RenKouDengji(Person per)

        {

            per.DengJi();

        }

多态的作用:把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。

==============================================

//如果转换失败报异常

//Chinese newcn = (Chinese)per;

// Chinese newcn = per as Chinese;

////类型转换,如果转换成功,则newcn中为转换后的结果

////如果转换失败,则newcn为null

Chinese newcn = per as Chinese;

二、 抽象类

1、 抽象方法不能有任何方法体。(不能有任何实现)public abstract void Show();

2、 抽象成员必须写在抽象类中。不能写在一个实例中。这个类也必须标记为abstract(抽象的)。

3、 父类中的抽象成员,子类继承后必须重写(例外:除非子类也是一个抽象类)

4、 抽象类中可以有抽象成员

5、 抽象类是不能被实例化的。(抽象类的作用就是为了继承)

6、 抽象类的特点总结

1> 抽象成员必须标记为abstract,并且不能有任何实现。

2> 抽象成员必须在抽象类中。

3> 抽象类不能被实例化。

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

5> 抽象成员的访问修饰符不能是private

6> 在抽象类中可以包含实例成员

7> 抽象类是有构造函数的,虽然不能实例化

7、 什么时候用抽象类,什么时候用virtual虚方法

1> 如果父类中的方法有默认的实现,并且父类需要实例化,这是可以考虑将父类定义成一个普通类,使用virtual虚方法来实现多态。

2> 如果父类中的方法没有默认的实现,父类也不需要被实例化,则可以将该类定义为抽象类。

3> 类中的成员如果不写访问修饰符默认是私有的

8、 new关键字隐藏父类的成员(用的很少)

1> 表示在子类中隐藏了从父类继承过来的那个虚方法,

子类类型 obj = new 子类类型

2> 用new标记的方法是子类中的一个全新的方法,与从父类中继承过来的方法没有一点关系(断截了)

3> 不能多态了。

9、 简单工厂设计模式

各种设计模式的本质都是:多态。(充分理解多态,再看设计模式就会觉得轻松很多。)

三、 接口(使用规范,给接口起名字是以I开头,able结尾)

1、 什么是接口?

1> 接口就是一种规范.约定好遵守某种规范就可以写通用的代码。

2、 接口的语法特点

1> 接口中只能包含方法(方法,属性,索引器,事件);

2> 接口中的方法也不能有任何实现(就像抽象方法一样,直接加分号);

3> 接口中的成员不能有任何访问修饰符(哪怕是public),默认是public;

4> 接口不能被实例化;

5> 实现接口的类,必须实现接口中所有的成员;

3、 都已经有类实现多态了,为什还要接口呢?

(1) 继承具有单根性,不能多继承。接口却可以多实现。

(2) 接口的主要目的就是要实现多态。

(3) 当同一个类同时继承了某个类,并且也实现了某个接口的时候,必须要将继承的类写到第一个位置。

wps_clip_image-8527 wps_clip_image-1247 wps_clip_image-13479 wps_clip_image-1430 wps_clip_image-25314 wps_clip_image-18402Public class Student : Person : IFlyable{}

(4) 当多个类型,都具有某个或某个功能时(方法),但是这几个类型又属于不同的系列(这几个类型没有共同的父类,这时就不能用抽象类了。),所以这时,为了实现多态就可以考虑把这几个类型的共有的方法提取到一个接口中,让这几个类型分别实现该接口。

(5) 如果一个类实现了一个接口,那么继承他的子类也会有接口里的内容。这个类的类型和这个类子类的类型都是他接口的类型(I…able)

4、 老师的建议:

建议:不要在一个接口中写过多的方法,避免造成接口污染。可以编写多个接口,在每个接口中,分别定义方法。(最终的是有还是要根据需求来定)

5、 显示实现接口:接口名.接口的方法IFlyable.Fly();