基本概念:关键词:virtual-override-base
作用:
- 让继承同一父类的子类们在执行相同方法时有不同的表现(多态);
- 让同一对象有唯一行为的特征。
特点:
- 父类方法中使用关键词:virtual,代表虚函数,可以被重写;
- 继承父类的子类的同名方法中使用关键词:override,代表重写父类的方法。
- 可以选用base.方法名来保留父类中的方法。
解决了一个问题:声明了一个父类和继承父类的子类,子类使用了父类的同名函数,在使用里氏替换原则时,用父类容器实例化子类对象时,不使用多态的情况下,无法使用.子类的方法。在使用了virtual-override-base的多态后,父类类型实例化子类对象,可以使用子类方法,同时可以选择保留父类方法。
其它:函数重载是一种编译时的多态,开始就写好了;virtual-override-base实现的是运行时的多态。
实例:
namespace 多态_virtual_override_base
{
class Father
{
public void Speak()
{
Console.WriteLine("这是父类的方法");
}
}
class Son1:Father
{
//new代表覆盖父类中的同名方法
public new void Speak()
{
Console.WriteLine("这是Son1子类的方法");
}
}
class GameObject
{
public string name;
public GameObject(string name) {this.name = name; }
//虚函数可以被重写
public virtual void Speak() { Console.WriteLine("这是GameObject!"); }
}
class Player : GameObject
{
public Player(string name):base(name)
{
}
//重写虚函数
public override void Speak()
{
//通过base保留父类的行为
base.Speak();
Console.WriteLine("这是Player!");
}
}
class Monster : GameObject
{
public Monster(string name):base(name) { }
public override void Speak()
{
Console.WriteLine("这是Monster!");
}
}
//练习题:创建一个图形类,有求面积和周长两个方法;
//创建矩形类,正方形类,圆形类继承图形类;
//实例化矩形、正方形、圆形对象求面积和周长;
class Graph
{
public float area;
public float perimeter;
public virtual float Area()
{
return area;
}
public virtual float Perimeter()
{
return perimeter;
}
}
class Rectangle : Graph
{
public float length;
public float width;
public Rectangle(float length, float width)
{
this.length = length;
this.width = width;
}
public override float Area()
{
area = length * width;
return area;
}
public override float Perimeter()
{
perimeter = 2 * length + 2 * width;
return perimeter;
}
}
class Square : Graph
{
public float sidelength;
public Square(float sidelength)
{
this.sidelength = sidelength;
}
public override float Area()
{
area = sidelength * sidelength;
return area;
}
public override float Perimeter()
{
perimeter = 4 * sidelength;
return perimeter;
}
}
class Circle : Graph
{
public float radius;
public const float pi = 3.1415926f;
public Circle(float radius)
{
this.radius = radius;
}
public override float Area()
{
area = radius * radius * pi;
return area;
}
public override float Perimeter()
{
perimeter = 2 * pi * radius;
return perimeter;
}
}
internal class Program
{
static void Main(string[] args)
{
Father i = new Son1 ();
i.Speak ();
(i as Son1).Speak();
GameObject gameObject1 = new Player("hi");
gameObject1.Speak ();
Graph g1 = new Rectangle(23,32);
Console.WriteLine("g1的面积是:{0},g1的周长是:{1}。", g1.Area(), g1.Perimeter());
Graph g2 = new Square(23);
Console.WriteLine("g2的面积是:{0},g2的周长是:{1}。", g2.Area(), g2.Perimeter());
Graph g3 = new Circle(10);
Console.WriteLine("g3的面积是:{0},g3的周长是:{1}。", g3.Area(), g3.Perimeter());
}
}
}