博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

【简述】:本章主要围绕面向对象的核心特性 继承与多态而展开,主要谈了方法重载、方法隐藏、方法重写、协变与逆变、多态编程的CLR原理等,其目的只有一个:实现多态编程。

 

第一节     方法的重载、隐藏与重写辨析

 1、 方法的重载的判定条件:

A、方法名相同。
B、方法参数列表不同。
   B.1 方法的参数数目不同。

   B.2 方法拥有相同数目的参数,但参数的类型不一样。

   B.3 方法拥有相同数目的参数和参数类型,但参数类型出现的先后顺序不一样。

       方法返回值类型不是方法重载的判定条件。

 2、 方法的隐藏:

A、  当子类与父类有完全一样的方法时,称子类隐藏了父类的同名方法。

B、  当分别位于子类与父类的两个方法完全一样时,调用哪个方法由对象变量的编译时类型决定。

C、  当定义方法隐藏时,需在子类中定义的同名方法前加 new 关键字。

class Parent {

  public void HideF() {Console.W riteLine(“Parent.HideF()”); 

}

class Child:Parent{

  public new void HideF() {Console.W    riteLine(“Child.F()”); 

}

Child c = new Child(); c.HideF();   //输出:Child.HideF()

Parent p = new Parent(); p.HideF();  //输出:Parent.HideF()

Parent x = new Child();  x.HideF();  //输出:Parent.HideF()

 3、方法重写与虚方法调用:

     A、在父类同名方法前加关键字Virtual,表明是一个虚方法。在子类同名方法前加关键字override,表明对父类同名方法进行了重写。

     B、调用同名方法时,由变量所引用对象的真实类型决定。

     C、正是C#的“虚方法调用”特性,使我们可以只用同样的一个语句,在运行时根据对象类型而执行不同的操作,让代码具有“运行时功能可变”的特性。

        Class Parent {

           Public virtual void f() {Console.WriteLine(“Parent.f()”);}

        }

        Class Child: Parent{

         Public override void f() { Console.WriteLine(“Child.f()”);}

        Parent b = new Parent();  b.f();  //输出:Parent.f()

        Child c = new Child();    c.f();  //输出:Child.f()

        b = c;  b.f();  //输出:Child.f()

        (b as Parent).f();  //输出:Child.f()

第二节   通过实例理解多态

 1、  多态编程:如果在编程时只使用基类和接口变量,而不使用具体的子类或实现接口的类,无疑就是一种“普遍性”的编程方式,会使代码具有更广的适合性。这种具有“普遍性”的编程方式,就是多态编程。

2、  多态编程的基本原理:使用基类或接口变量编程----依赖抽象编程,而不是依赖具体编程。

A、  基类一般都是抽象基类,其中拥有一个或多个抽象方法,各个子类可以根据需要重写这些方法。

B、  使用接口,为每个接口定义一个或多个方法,由实现接口的类根据实际需要提供这些方法的具体实现。

3、  多态的实现:继承多态和接口多态。

4、  小结:应用继承实现对象的统一管理,应用接口定义对象的行为特性。

第三节   协变与逆变

 1、  协变:如果一个泛型接口(泛型委托)的类型参数前有一个out关键字,那么此类型参数可以接收子类型。  public interface IEnumerable<out T>:IEnumerable

           {   Ienumerator<T> GetEnumerator();  }

            IEnumerable<string> strings = ……;

            IEnumerable<object> objects = strings;

2、逆变:如果一个泛型接口(泛型委托)的类型参数前有一个in关键字,那么此类型参数可以接收父类型。      Public delegate void Action<in T>(T obj);

          Static void ParentFunc(Parent p) {}

          Action<Child> del = ParentFunc;

3、 协变与逆变特性同样适合于非泛型的委托。

          Public delegae Parent MyDelegate();

          MyDelegate del = delegate(){

            Return new Child();}