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)调用
定义结构-->声明变量-->赋值-->使用