多态机制
1.编译时多态
- 重载
2.运行时多态
- 虚函数
虚函数
- 对于基类中要实现多态性的方法,用virtual关键字修饰。不 允许再有static,abstract或override修饰符。
- 对于派生类中的同名方法(覆盖) --相同的名称、返回类型和 参数表,使用override关键字修饰。不能有new、static或 virtual修饰符。
1.父类方法前加virtual关键字,表示该方法可以被覆盖;子 类方法前加override,表示将方法覆盖。
2.使用virtual声明虚方法,用override来重写虚方法。
3.多态的本身指的就是不同的对象在收到相同的消息时产生不同的动作
4.在存在多层派生继承的时候,子类若没覆盖虚方法,在调用该方法时将调用最近父类的方法。
class GeometricObject
{
public virtual void draw(
{
Console.WriteLine("GeometricObject!");
}
}
class Ellipse:GeometricObject
{
public override void draw()
{
Console.WriteLine("Ellipse!");
}
public void getvecter(){}
}
class Circle:Ellipse
{
public override void draw()
{
Console.WriteLine("Circle!");
}
public double getArea()
{
return 1.0;
}
}
main()函数中的代码 GeometricObject g=new Circle();
//父类型引用指向子类型对象g.draw();
g.draw(); //draw调用的是哪个类的方法? Cirle!
如果g换成Circle类引用呢? Ellipse!
如果Circle类不覆盖draw方法,调用的是哪个类的方法?
double d=g.getArea(); // 该语句编译时不能通过
重载与覆盖
- 相同点
都涉及两个同名方法。 - 不同点
1.类层次
(1).重载涉及的是同一个类的两个同名方法;
(2).覆盖涉及的是子类的一个方法和父类的一个方法, 这两个方法同名。
2.参数和返回值
(1).重载的两个方法具有不同的参数,可以有不同返回值类型;
(2).覆盖的两个方法具有相同的参数,返回值类型必需相同。 - new和override的区别
1. new修饰的方法表示显式隐藏基类继承的同名方法,不能够用基类的引用访问派生类的new方法。
2. override表示重写基类的虚方法,可以用基类的引用指向派生类对象来访问派生类的重写方法。 - 虚属性
类似于虚方法,由virtual修饰,在派生类中依然用override来重写。
密封类
- 类似于public、private等,密封类用sealed修饰,且不可被继承。
public sealed class Runtime
{
private Runtime();// 私有构造不允许其他代码建立类实例
public static string GetCommandLine()// 静态方法成员
{
…… // 实现代码
}
}
public class anotherclass:Runtime //错误,不能继承密封类
{
…… //实现代码
}
抽象类
- 相较于密封类,抽象类使用abstract修饰。
- 抽象方法是虚方法的特例。
- 子类若覆盖抽象方法,依然需要override声明。
- 构造函数和静态方法不能是抽象的。
- 如果在抽象类在派生时,其子类未能将所有抽象成员实现,则该派生类仍为一个抽象类。
abstract class WashingMachine
{
public WashingMachine()//构造函数
{
Console.WriteLine("here is WashingMachine ");
}
abstract public void Wash(); //抽象方法
abstract public void Rinse(int loadSize); //抽象方法
abstract public long Spin(int speed); //抽象方法
}
接口
[访问修饰符] interface 接口标识符 [:基接口列表]
{
接口体;
}
- 接口成员访问权限为public,但是不能加访问修饰符!
- 接口成员不能有定义。
- 接口成员必须是方法,属性,事件或索引器,不能包含常数、字段、运算符、实例构造函数、析构函数或类型。
//基本形式
interface A
{
void f();//没有函数体,也不加修饰符
public void f();//错误
void f(){}//错误
}
- 接口的实现需要用":"来继承
接口与对象的区别
对于接口Comparable:
(1).接口不是类,所以不能用接口创建对象,即不能用new 运算符。 x = new Comparable(); //错误
(2).可以声明接口类型的引用,该引用只能指向实现了该接 口的对象。
is运算符
- if ( obj is Classname )
……
as运算符
- as 运算符完成的功能等价于:先用is检查, 再执行对象类型转换。
- 如果类型不兼容,as运算返回null。
结构体
访问修饰字 struct 结构名[:接口]
{
结构体
}
- 不支持继承,但可以继承接口
- 对于结构体的构造函数,必须带参数,且必须对字段进行赋值。
- !!!结构体是值类型,类是引用!!!