2.C#.Net多态之抽象类、虚方法与接口

  1.虚方法和抽象方法的区别

  (1)虚方法中必须有实现,抽象方法中必须没有实现。

  (2)抽象方法必须在抽象类中声明,虚方法可以出现在抽象类中。

  (3)抽象方法必须在子类中重写,虚方法可以被重写。

  2.实现多态的主要手段

  (1)虚方法,vitural

  (2)抽象方法abstract

  (3)接口

  3.关于虚方法中需要注意的几点

  (1)父类中如果有方法需要让子类重写,则可以将该方法标记为virtual

  (2)虚方法在父类中必须有实现,哪怕是空实现。

  (3)虚方法(virtual)子类可以重写(override),也可以不重写。

  4.抽象方法和抽象类 abstract的使用注意:

  (1)抽象方法没有方法体

  (2)抽象成员只能存在于抽象类中

  (3)抽象类可以有非抽象成员

  (4)抽象类的派生类必须实现抽象方法体

  (5)抽象类只能用作基类,无法实例化。

  (6)抽象类不能被实例化,只能被其它类继承

  (7)继承抽象类的子类必须把抽象类中的所有抽象成员都重写,除非子类也是抽象类

  (8)抽象类就是为了重写――>多态。

  (9)抽象类中的抽象成员不能使用private访问修饰符,可以使用其它访问修饰符

  6.多态就是为了程序的可扩展性,把不同的子类对象都当作父类对象来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。

  7.里氏替换原则

  (1)父类引用指向子类对象 Person P=new Chinese();

  (2)父类对象不能够替换子类 Chinese c=new Person();<--错误!!!-->

  8.is和as

  //使用as,如果转换失败也不会报错,会将null赋值给c。

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

  //as关键字只能判断引用类型

  Chinese c=per as Chinese();

  if(c!=null)

  {

  Do something......

  }

  Chinese cn=(Chinese)per;//如果转换失败就会报错!!!

  9.接口

  类实现接口,可以显示的实现接口里的方法,但是注意,一旦使用显示接口里的方法后,那么该方法只能被 接口变量 调用。

  IFlyable fly=new Bird();

  fly.Fly();//正确

  Bird fly=new Bird();

  fly.Fly();//错误

  10.小结

  封装:

  ref:传递前就要赋值,方法外赋值,在方法内使用。

  out:在方法中必须赋值。

  param:主要是修饰数组参数,在参数列表中只能有一个,并且只能放在最后。

  继承:

  目的:

  1代码的复用,子类继承父类所有的成员,但是只能访问非私有的成员。

  2多态:LSP--父类 obj=new 子类();

  (2.1)如果子类和父类存在相同的方法。

  (2.1.1)参数列表不相同:构成子类中的方法重载,也就是子类中包含两个同名方法(参数列表不同).

  (2.1.2)参数列表不相同:

  (2.1.2.1)如果同名方法不存在重写关系(子类没有重写父类方法):

  Example One:父类 obj=new 子类();

  obj.SayHello();//执行父类的SayHello方法;

  Example Two:子类 obj=new 子类();

  obj.SayHello();//执行子类的SayHello方法,此时,子类对象中隐士的隐藏了父类的SayHello方法。也可以通过new来显示隐藏。

  (2.1.2.2)如果子类重写了父类的方法(前提:父类的方法必须是虚方法/抽象方法,子类通过override关键字重写)

  Example One:父类 obj=new 子类();

  obj.SayHello();//执行子类的SayHello方法

  子类 obj=new 子类();

  obj.SayHello();//执行子类的SayHello方法

  多态:

  多态的常用方式:

  (2.2.1)简单工厂方式,以返回值的方式来使用

  父类 obj=FactoryMethod("a");//在简单工厂方法中,通过判断参数来创建相应的子类对象,并返回给父类使用。

  obj.SayHello();

  好处:父类不关心具体的实现,只要针对父类中能够访问到的成员来编写下面代码就可以了。

  (2.2.2)父类做参数使用

  public void Test(父类 o)

  {

  o.SayHello();//此方法中不关心传进来的对象具体方法的实现代码,只关心能调用什么方法;

  }

  子类 obj=new 子类();

  Test(obj);

  11.静态类小结

  (1)普通类中的静态成员

  --只能通过类名访问(类名.静态成员)

  --静态方法中只能访问静态成员,或通过对象访问实例成员

  --多个对象共享一个静态成员

  (2)静态类

  --Maht、Console、Convert都是静态类。

  --静态类中只能包括静态成员。

  --静态构造函数不能有参数,不能有访问修饰符(默认为private)。

  (3)静态成员属于类所有,非静态成员属于类的实例所有。

  (4)静态方法属于类所有,类实例化前即可使用。

  (5)在实例方法中可以直接调用静态方法,在静态方法中不可以直接调用实例方法。

  (6)静态方法和静态变量创建后始终使用同一块内存(静态存储区),而使用实例的方式会创建多个内存。

  (7)少使用静态类,静态类、静态成员所分配的内存在程序推出时才会释放。

  (8)静态构造函数必须用static标记

  静态构造函数不能有访问修饰符

  静态构造函数不能有参数

  静态构造函数只会被调用一次。在第一次使用静态类前。

  (9)静态类不能被实例化,就不会有对象,而this表示的是当前对象。所以静态类不能使用this

  代码:

  static StaticClass()

  {

  //Do Something

  }

  12.什么时候使用静态类、静态变量?

  (1)当多个对象共享同一个数据的时候就可以在实例类中加入静态成员。

  (2)在项目中需要频繁用到的一些工具类,或者模拟全局变量的时候。

  13.静态类的继承问题

  (1)静态类不能被其它类继承。

  (2)sealed:密封类,不能被继承,例:String类

  (3)静态类的本质:abstract+seald

  (*)不想让子类继续重写该方法时,可以用seald关键字标记该方法。

  sealed与override必须一起使用

  public sealed override SayHello()

  {

  base.SayHello();

  }

  14.结构体

  (1)结构体是一个 值类型 。非常像类的一种值类型,不具有面向对象的特征,通常用来封装小型相关变量。

  (2)System.Drawing.Point、Size、Color

  (3)注意:

  --结构使用是可以new,也可以不new。如果不new,则使用前必须为结构成员赋值

  --在结构中不能为变量直接赋初值,除非const(常量)、static(静态变量)

  (4)结构的使用方法和类很像,什么使用类?什么时候使用结构?

  --(1)是否需要使用面向对象的特征:封装、继承和多态。如果需要在某些条件下被继承或者使用多态等特性则只能使用类。

  (5)语法

  public struct 结构名

  {

  public 类型名 变量名;

  ......

  }

  (6)调用

  定义结构-->声明变量-->赋值-->使用


你可能感兴趣的:(抽象类,虚方法与接口)