继承和多态都是面向对象程序设计的特点。使用继承可以在一个父类的基础上再创建一个子类,这个子类不但拥有父类已有的属性和方法,还可以创建属于自己的属性和方法。由于子类和父类之间的关系,从而引出了方法重写和方法重载的问题。方法重写及方法重载在继承和多态性方面的应用中会存在很多问题,这些概念很容易混淆,掌握重写和重载的区别对学会使用多态的方式编写程序、提高程序的可维护性奠定了基础。
一、方法重写(overriding)
如何定义重写:在java程序中,类的继承关系可以产生一个子类,子类继承父类,它具备了父类所有的特征,继承了父类所有的方法和变量。子类可以定义新的特征,当子类需要修改父类的一些方法进行扩展,增大功能,程序设计者常常把这样的一种操作方法称为重写,也叫称为覆写或覆盖。重写体现了java优越性,重写是建立在继承关系上,它使语言结构更加丰富。在java中的继承中,子类既可以隐藏和访问父类的方法,也可以覆盖继承父类的方法。在java中覆盖继承父类的方法就是通过方法的重写来实现的。
所谓方法的重写是指子类中的方法与父类中继承的方法有完全相同的返回值类型、方法名、参数个数以及参数类型。这样,就可以实现对父类方法的覆盖。例如:下面的代码实现了方法的重写。
class person//定义父类
{public void print(){//父类中的方法
system.out.println("父类person的print方法!");
}
}
class student extends person//定义子类继承person类
{public void print(){//方法的重写
system.out.println("子类student的print方法!");
}
}
public class overrideexample01
{public static void main(string args[])
{student s=new student();
s.print();
}
}
运行结果:子类student的print方法!
可以看出,当子类重写了父类中的print()方法后,使用s调用的是子类的print()方法,父类中的print()方法被覆盖了。也就是说,如果现在子类将父类中的方法重写了,调用的时候肯定是调用被重写过的方法,那么如果现在一定要调用父类中的方法该怎么办呢?此时,通过使用super关键就可以实现这个功能,super关键字可以从子类访问父类中的内容,如果要访问被重写过的方法,使用“super.方法名(参数列表)”的形式调用。例如:
class person
{public void print(){
system.out.println("父类person的print方法!");
}
}
class student extends person
{public void print(){
super.print(;//访问父类中被子类覆写过的方法
system.out.println("子类student的print方法!");
}
}
public class overrideexample02
{public static void main(string args[])
{student s=new student();
s.print();
}
}
运行结果:父类person的print方法!
子类student的print方法!
如果要使用super关键字不一定非要在方法重写之后使用,也可以明确地表示某个方法是从父类中继承而来的。使用super只是更加明确的说,要从父类中查找,就不在子类查找了。
二、重写规则
在重写方法时,需要遵循以下的规则:
(一)父类方法的参数列表必须完全与被子类重写的方法的参数列表相同,否则不能称其为重写而是重载。
(二)父类的返回类型必须与被子类重写的方法返回类型相同,否则不能称其为重写而是重载。
(三)java中规定,被子类重写的方法不能拥有比父类方法更加严格的访问权限。访问权限大小关系为:private<default<protected<public。
编写过java程序的人就知道,父类中的方法并不是在任何情况下都可以重写的,当父类中方法的访问权限修饰符为private时,该方法只能被自己的类访问,不能被外部的类访问,在子类是不能被重写的。如果定义父类的方法为public,在子类定义为private,程序运行时就会报错。例如:
class person
{public void print(){//public访问权限
system.out.println("父类person的print方法!");
}
}
class stedent extends person
{private void print(){//重写方法降低了访问权限,错误
system.out.println("子类student的print方法!");
}
}
(四)由于父类的访问权限修饰符的限制一定要大于被子类重写方法的访问权限修饰符,而private权限最小。所以如果某一个方法在父类中的访问权限是private,那么就不能在子类中对其进行重写。如果重新定义,也只是定义了一个新的方法,不会达到重写的效果。
(五)在继承过程中如果父类当中的方法抛出异常,那么在子类中重写父类的该方法时,也要抛出异常,而且抛出的异常不能多于父类中抛出的异常(可以等于父类中抛出的异常)。换句话说,重写方法一定不能抛出新的检查异常,或者比被重写方法声明更加宽泛的检查型异常。例如,父类的一个方法申明了一个检查异常ioexception,在重写这个方法时就不能抛出exception,只能抛出ioexception的子类异常,可以抛出非检查异常。
同样的道理,如果子类中创建了一个成员变量,而该变量和父类中的一个变量名称相同,称作变量重写或属性覆盖。但是此概念一般很少有人去研究它,因为意义不大。
三、方法重载(overloading)
(一)如何定义重载。方法的重写和重载只有一个字不同,很多初学者认为这两者十分相似,其实不然。方法重载是让类以统一的方式处理不同类型数据的一种手段。调用方法时通过传递给它们的不同个数和类型的参数来决定具体使用哪个方法,这就是多态性。
所谓方法重载是指在一个类中,多个方法的方法名相同,但是参数列表不同。参数列表不同指的是参数个数、参数类型或者参数的顺序不同。方法的重载在实际应用中也会经常用到。不仅是一般的方法,构造方法也可以重载。下面通过一个实例来分析重载的定义和使用方法。
class person
{string name;
int age;
void print(){
system.out.println("姓名:"+name+"年龄:"+age);
}
void print(string a,int b){
system.out.println("姓名:"+a+"年龄:"+b);
}
void print(string a,int b,int c){
system.out.println("姓名:"+a+"年龄:"+b+"id号:"+c);
}
void print(string a,int b,double c){
system.out.println("姓名:"+a+"年龄:"+b+"id号:"+c);
}
}
public class overloadexample01
{public static void main(string args[])
{person p1=new person();
p1.name="李明";
p1.age=22;
p1.print();
p1.print("王小早",19);
p1.print("金波",18,100325);
p1.print("婉宁",25,110903);
}
}
在上面的程序中,可以看到person类中有多个名为void print的方法,这就是方法的重载。执行程序,运行结果如下:
姓名:李明 年龄:22
姓名:王小早 年龄:19
姓名:金波 年龄:18 id号:100325
姓名:婉宁 年龄:25 id号:110903
在方法重载时,方法之间需要存在一定的联系,因为这样可以提高程序的可读性,一般只重载功能相似的方法。
(二)重载规则。重载是指我们可以定义一些名称相同的方法,通过定义不同的参数来区分这些方法,然后再调用时,java虚拟机就会根据不同的参数列表来选择合适的方法执行。也就是说,当一个重载方法被调用时,java用参数的类型和(或)个数来决定实际调用的重载方法。因此,每个重载方法的参数的类型或个数必须是不同。虽然每个重载方法可以有不同的返回类型,但返回类型并不足以区分所使用的是哪个方法。当java调用一个重载方法是,参数与调用参数匹配的方法被执行。在使用重载要注意以下的几点:
1.在使用重载时只能通过不同的参数列表,必须具有不同的参数列表。例如,不同的参数类型,不同的参数个数,不同的参数顺序。当然,同一方法内的几个参数类型必须不一样,例如可以是fun(int,float),但是不能为fun(int,int)。
2.不能通过访问权限、返回类型、抛出的异常进行重载。
3.方法的异常类型和数目不会对重载造成影响。
4.可以有不同的返回类型,只要参数列表不同就可以了。
5.可以有不同的访问修饰符。
6.可以抛出不同的异常。
四、方法重写与方法重载的区别
通过上面例子的分析,我们可以将方法重写和重载的区别总结成这样一个表格,如下:
区别点重载重写(覆写)
单词overloadingoverriding
定义方法名称相同,参数的类型或个数不同方法名称、参数类型、返回值类型全部相同
对权限没有要求被重写的方法不能拥有更严格的权限
范围发生在一个类中发生在继承类中
五、结束语
在面向对象程序设计的思想中,类的继承和多态性主要就是体现在子类重写父类的方法。而构造方法的重载作为方法重载的一个典型特例,可以通过重载构造方法来表达对象的多种初始化行为。灵活的运用方法重写与方法重载,不仅能减少编码的工作量,也能大大提高程序的可维护性及可扩展性。用好重写和重载可以设计一个结构清晰而简洁的类,可以说重写和重载在编写代码过程中的作用非同一般。
分享到:
相关推荐
重载的条件: 1.必须在同一个类中2.方法名必须相同3.参数列表不能相同。...只能调用父类的实例方法 this()调用该类的其他构造方法,this.调用类的属性,方法 如果父类有有参构造,子类必须定义构造方法
方法重写与重载;理解方法重写 理解方法重载与重写本质上的不同 能够在子类中正确编写代码覆盖父类的方法 ;public class Person { public void display() { System.out.println("id: " + this.id); System.out....
关于java方法重写的Mypet实例,希望能够为新手学习用
// 下面几个方法用来验证可以通过定义不同的参数类型和参数的数目进行方法重载。 public void fun(){ System.out.println("method fun in OverloadTest, no parameter"); } public void fun(float f) { System...
本文主要介绍Java 的重载和重写,学习java的同学都知道Java的多态有多重要,这里给大家举例说明函数的重载和重写,希望能帮助有需要的小伙伴
Delphi--抽象方法、重载、覆盖。继承实例Delphi--抽象方法、重载、覆盖。继承实例
主要介绍了实例分析java中重载与重写的区别,需要的朋友可以参考下
本篇文章通过实例详细介绍了重写与重载,以及他们的区别,需要的朋友可以参考下
主要介绍了C#中多态、重载、重写区别,采用实例较为通俗易懂的分析了多态、重载的重写的概念与用法,对于C#初学者有非常不错的借鉴价值,需要的朋友可以参考下
主要介绍了java 重载(overload)与重写(override)详解及实例的相关资料,并附实例代码,需要的朋友可以参考下
主要介绍了C++中重载、重写(覆盖)和隐藏的区别,是C++面向对象程序设计非常重要的概念,需要的朋友可以参考下
实例111 使用重载方法实现不同类型数据的计算 135 5.2 结构与类 136 实例112 通过结构计算矩形的面积 136 实例113 通过类继承计算梯形面积 137 实例114 封装类实现一个简单的计算器 139 实例115 使用面向对象思想...
本文实例讲述了PHP面向对象程序设计(OOP)之方法重写(override)操作。分享给大家供大家参考,具体如下: 因为PHP是弱类型的语言, 所以在方法的参数中本身就可以接收不同类型的数据,又因为PHP的方法可以接收不定...
理论对应实例,各自讲解加区别。绝对可以帮到你。
Python语言本身提供了很多魔法方法,它的运算符重载就是通过重写这些Python内置魔法方法实现的。这些魔法方法都是以双下划线开头和结尾的,类似于__X__的形式,python通过这种特殊的命名方式来拦截操作符,以实现...
1.static在类的字段和方法中,只有通过类名能访问,不能通过类的实例进行访问 2.方法重载;指在类中可以定义多个名称相同但方法签名不同的方法;“方法签名不同”指方法的参数顺序,参数类型和参数个数不同。(方法...
主要介绍了Java 重载、重写、构造函数的实例详解的相关资料,希望通过本文大家能理解掌握java 面向对象的方法,需要的朋友可以参考下
本文实例讲述了C++中重载、重写(覆盖)和隐藏的区别,对于C++面向对象程序设计来说是非常重要的概念。具体分析如下: 1.重载:重载从overload翻译过来,是指同一可访问区内被声明的几个具有不同参数列(参数的...