【前言】
重载和重写,他们其实是实现类型多态(同一种方法,不同的对象会产生不同的结果)特性的基本技术之一,两种技术貌似而实质截然不同
【重载】
1、什么是重载
重载其实是一种编译时多态技术,就是说在编译时就知道调用的是哪个方法,这其实很好理解。所谓重载就是在同一个类中的多个同名方法,只是这些方法的参数类表不同(参数个数,或者是相同位置的参数类型不同)而已,而返回值可以相同也可以不同,这些方法具有不同的方法签名。也就是说不同的方法,从编译器的角度,不同的方法就是不同的方法地址,在编译时就已经确定,是一种静态绑定
2、格式
//用于在给定了参数列表和一组候选函数成员的情况下,选择一个最佳函数成员来实施调用
public void test(int x,int y){}
public void test(int x,ref int y){}
public void test(int x,int y,string a){}
3、重载的特征
(1)方法名必须相同
(2)参数列表必须不相同,与参数列表的顺序无关
(3)返回值类型可以不同
4、重载的特点
(1)在使用重载的时候只能通过不同的参数样式。例如,不同的参数类型,不同的参数个数,不同的参数顺序(当然,同意方法内的几个参数类型必须不一样,例如可以是fun(int, float),但是不能为fun(int,int))
(2)不能通过访问权限、返回类型、抛出的异常进行重载
(3)方法的异常类型和数目不会对重载造成影响
(4)对于继承来说,如果某一方法在父类中是访问权限priavte,那么就不能在子类对其进行重载,如果定义的话,也只是定义了一个新方法,而不会达到重载的效果
5、例子
建立一个猫类,在这个类中构造两个方法。一个是带参数姓名的方法,另一个是不带参数姓名的方法。这样初始化一个“猫”的对象时,就可以选择给对象起名或者不起名,从而达到扩展的目的
class Cat
{
public string name= " ";
public Cat(string name)
{
this.name=name;
}
public Cat()//将方法重载
{
this.name="无名";
}
}
【重写】
1、什么是重写
重写也叫做覆盖,它存在于有继承关系的子类中,是在子类中重新定义父类具有相同方法签名的函数,使之有不用的实现。重写是指重写基类的方法,在基类中的方法必须有修饰符virtual,而在子类的方法中必须指明override
例如,假设动物类存在“跑”的方法,从中派生出马和狗,马和狗的跑的形态是各不相同的,因此同样方法需要两种不同的实现,这就需要“重新编写”基类中的方法
2、格式
//在基类中
public virtual void myMethod()
{
}
//在子类中
public override void myMethod()
{
}
3、重写的特征
(1)必须在继承里
(2)方法名、参数个数和参数类型都必须相同
(3)派生类重写的方法的访问权限不能低于基类的权限
(4)派生类抛出的异常应该和基类相等或比基类更小
需要注意的地方:
(1)如果有泛型的时候需要注意,子类继承父类的时候可能出现同名但方法定义不同的情况,所以在子类中会将原方法覆盖,实现自身的要求
(2)可以在子类被重写的方法一定要标记成virtual(虚拟),abstract(抽象),override(重写)标记为virtual和abstract的函数就是为了重写而创建的,标记为override的函数本身是由前两种函数重写而来的,所以它可以被重写也是顺理成章的了
(3)重写的函数必须在子类中出现,而且任何一个父类的函数在其一个子类中只能被重写一次
4、覆盖需要注意的地方
(1)覆盖的方法的标识必须要和被覆盖的方法的标志完全匹配,才能达到覆盖的效果
(2)覆盖的方法的返回值必须和被覆盖的方法的返回一致
(3)覆盖的方法所抛出的异常必须和被覆盖方法的所抛出的异常一致,或者是其子类
(4)被覆盖的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行覆盖
5、例子
比如,动物都有“叫”的方法。猫和狗是它的子类,猫的叫声是“喵”,狗的叫声是“汪”,如何在子类中重写父类的方法呢?首先在动物类中构造一个虚方法。在构建猫这个类时,重写“叫”这个方法;在构建狗这个类时,也重写“叫”这个方法。重写发生在父类和子类之间,声明的是父类,实例化的是子类。本例子实现了多态
class Animal
{
public virtual string Shout()//修饰符中增加了一个virtual,表示此方法是虚方法,可以被子类重写
{
return "";
}
}
class Cat : Animal
{
public override string Shout()//override,表示方法被重写
{
string result="喵";
return result;
}
}
class Dog : Animal
{
public override string Shout()
{
string result="汪";
return result;
}
}
重载必须发生在一个类中,方法名相同,参数不同。值得注意的是,方法重载必须通过参数不同来判断调用哪个方法,而不能通过返回值
重写一般用于接口实现和继承类的方法改写。值得注意的是,被覆盖的方法不能为private,否则在其子类中只是重新定义了一个方法,并没有进行覆盖
本文只是对基础知识做一个小小的总结,不深究。如有不同,见解欢迎指正
本文所有代码均已通过作者测试
本文所有内容均为作者原创,如有转载,请注明出处