前言:通过阅读这篇文章能更好的理解C#中的重写,以及重写在什么时候使用,推荐刚入门的小伙伴收藏嗷!!!
一、重写的含义
在父类中有一个方法,但是子类中也需要这个方法的名称,但是子类中的方法的逻辑与父类方法中的逻辑不相同,则需要在子类中对这个方法进行重写。也就是说在继承时,如果在派生类中不想使用基类中的方法体时,可以在派生类中重写该基类方法,实现派生类与基类同名不同方法体的方法。重写父类方法就是修改它的实现方式或者说在子类中对它进行重新编写。
二、重写的作用
- 使基类的虚属性和虚函数在整个继承链中都不可见(在子类中用base关键字调用除外)
- 在软件开发过程中,便于维护、扩展。
三、怎么样重写
1.重写父类的方法要用到override
关键字(具有override
关键字修饰的方法是对父类中同名方法的新实现)
2.要重写父类的方法,前提是父类中该要被重写的方法必须声明为virtual
或者是abstract
类型。给父类中要被重写的方法添加virtual
关键字表示可以在子类中重写它的实现;给父类中要被重写的方法添加abstract
关键字表示在子类中必须重写它的实现。(注意:C#中的方法默认并不是virtual类型的,因此要添加virtual
关键字才能够被重写)
3.virtual
关键字用于将方法定义为支持多态,abstract
关键字使基类方法没有具体实现方式,也就是说基类的这个方法在调用后没有任何功能实现,但是必须在子类中重写它。有virtual
关键字修饰的方法称为“虚拟方法”,同样具有abstract
关键字的方法称为“抽象方法”。方法名、参数列表和访问修饰符都是不能修改的,必须与父类一样。否则编译器会报错
**该方法使用与之相同的签名(方法名、参数列表),另外,
[访问修饰符] virtual [返回类型] 方法名(参数列表)
{
//虚拟方法的实现,该方法可以被子类重写
}
[访问修饰符] abstract [返回类型] 方法名(参数列表)
{
//抽象方法的实现,该方法必须被子类重写
}
四、为什么要重写
通常,子类继承父类的方法,在调用对象继承方法的时候,调用和执行的是父类的实现。但是,有时候需要对子类中的继承方法有不同的实现方式,这时就用到了方法重写。
1.调用子类继承的父类中的方法
class Peopole
{
public void run()
{
Console.WriteLine("人类会跑步");
}
}
class Man : Peopole
{
}
class Program
{
static void Main(string[] args)
{
Man man = new Man();
man.run();
Console.ReadLine();
}
}
由此可见,虽然实例化的是子类,但是调用的是父类的方法。
2.子类中出现与父类中同名的方法
class Peopole
{
public void run()
{
Console.WriteLine("人类会跑步");
}
}
class Man : Peopole
{
public void run()
{
Console.WriteLine("男人会跑步");
}
}
class Program
{
static void Main(string[] args)
{
Man man = new Man();
man.run();
Console.ReadLine();
}
}
如果父类中有一个方法,则子类中默认是不允许出现同名方法,如果出现了则系统认为是子类中要隐藏父类中的这个同名方法,那么在子类对象调用方法之后则调用到的是子类中的方法,但是程序会警告我们隐藏父类中的同名方法应该通过添加new
关键字或者添加override
关键字来实现。
五、重写具体使用
class Peopole
{
//使用虚方法需要使用virtual关键字
public virtual void run()
{
Console.WriteLine("人类会跑步");
}
public virtual void say()
{
Console.WriteLine("人类会说话");
}
}
class Man : Peopole
{
//重写方法
public override void run()
{
//前面发布过关于base关键字在继承时候的用法
base.run();//调用基类run方法
Console.WriteLine("男人会跑步");
}
public override void say()
{
base.say();//调用基类say方法
Console.WriteLine("男人会说话");
}
}
abstract class Person
{
//使用抽象方法时,方法对应的类必须是抽象类,并且抽象方法不能有主体(具体表现)
public abstract void study();
public abstract void song();
}
class Children : Person
{
//继承一个抽象类,子类中一定全部重写父类中的所有抽象方法
public override void study()
{
Console.WriteLine("小孩学习");
}
public override void song()
{
Console.WriteLine("小孩唱歌");
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("===========重写=============");
Console.WriteLine("===虚方法重写===");
Man man = new Man();
//系统会自动将子类man对象隐式转换为Peopole类型(隐式实现了一次装箱) ,也就是先Man p = new Man();然后Peopole man= p;所以这里还是调用了Man类中的方法
man.run();
man.say();
Console.WriteLine("===抽象方法重写===");
Children children = new Children();
children.study();
children.song();
Console.ReadLine();
}
}
拓展:
base
关键字用于从子类中访问父类成员。即使父类的方法在子类中重写,仍可以使用base关键字调用。在创建子类实例时,可以使用base关键字调用父类的构造函数。但是使用base关键字只能访问父类的构造函数、实例方法或实例属性,而不能访问基类的静态方法。
通过阅读这篇文章你收获了多少呢?但是请记住功夫不负有心人,加油吧少年;若有问题可以提出来,评论区见!!!
转载:https://blog.csdn.net/liu991029/article/details/106816370