首先来一段代码,看一下继承的关系
class Monster
{
public void BeHit()
{
Console.WriteLine("基类Behit");
}
}
class Slam : Monster
{
public void BeHit()
{
Console.WriteLine("打史莱姆");
}
}
class Mario : Monster
{
public void BeHit()
{
Console.WriteLine("打马里奥");
}
}
class Program
{
static void Main(string[] args)
{
Monster mo = new Monster();
Mario m = new Mario();
Slam s = new Slam();
mo.BeHit();
m.BeHit();
s.BeHit();
Console.ReadKey();
}
}
创建了三个类,其中slam和mario继承了monster,三个类中有同名函数BeHit();
所以我们知道了第一点
1.子类的方法可以与父类的方法同名
main函数中分别创建了三个类的对象,执行了同名方法
运行结果,果然就是每个类的实例运行各自的方法
基类Behit
打马里奥
打史莱姆
尝试一下别的情况
class Program
{
static void Main(string[] args)
{
Mario m = new Mario();
m.BeHit();
Monster monster = m;
monster.BeHit();
Mario n = (Mario)monster;
n.BeHit();
Console.ReadKey();
}
}
运行结果
打马里奥
基类Behit
打马里奥
首先声明了 Mario m = new Mario();
然后运行,输出肯定是 打马里奥 没有疑问。
然后声明了 Monster monster = m; 没有报错
知道了:
2.父类的变量,可以指向子类的对象
此时再monster.BeHit();执行的是父类的方法,输出 基类Behit
这里我尝试将Mario()中的方法改名为BeHit1();然后monster.BeHit1(),系统报错
那么虽然monster和m本质是同一个对象,但是monster只能在父类中寻找方法,而m是在子类中寻找方法。
3.某种情况下,强制类型转换可以将父类对象转化成子类对象
Mario n = (Mario)monster; 不会报错,因为monster原本就是Mario类型的m转化的,输出 打马里奥 没有疑问
Slam p = (Slam)monster;显示不报错,执行报错
Slam p = (Slam)m;显示红线报错
使用virtual和override关键字,进行方法的重写
class Monster
{
public virtual void BeHit()
{
Console.WriteLine("基类Behit");
}
}
class Slam : Monster
{
public override void BeHit()
{
Console.WriteLine("打史莱姆");
}
}
class Mario : Monster
{
public override void BeHit()
{
Console.WriteLine("打马里奥");
}
}
class Program
{
static void Main(string[] args)
{
Monster m = new Mario();
Monster n = new Slam();
m.BeHit();
n.BeHit();
//p.BeHit();
Console.ReadKey();
}
}
1.父类中要被重写的方法必须用virtual或者是abstract修饰。
2.子类中用override修饰方法重写父类方法
这次运行
Monster m = new Mario();
Monster n = new Slam();
m.BeHit();
n.BeHit();
输出为:
打马里奥
打史莱姆
另外:
virtual修饰的方法叫虚方法,virtual修饰的可以有方法体,子类不一定要重写
abstract修饰的方法叫抽象方法,abstract修饰的没有方法体,子类必须要重写
抽象方法只能在抽象类中声明,虚方法不是;