Java——重载和重写

前言

在程序设计中经常会遇到对对方法的重载或者重写,下面将介绍重载和重写。

重载(Overloade)

重载出现的原因

任何程序设计语言都具备的一项重要特性就是对名字的运用。当创建一个对象时,就给对象的存储空间取了一个名字。方法名就是给某个动作取的名字。通过使用名字,我们可以引用所有对象和方法。名字起的好可以使程序更易于理解和修改。

在大多数程序设计语言中要求为每个方法提供唯一的标识符。不能使用print()的函数显示了整数之后,又用一个名为print()的函数显示浮点数。即,每个函数(方法)都要有唯一的名称。这是迫使出现重载方法的理由之一。若是print()函数可以被重载了,那么就既可以输出整数也可以输出浮点数。或者又可以举例:我们要计算两个整数相加,我们可以设计方法为int add(int a, int b)。调用add(10,10)我们就可以知道是计算两个整数相加。此时,我们又想计算两个浮点数相加,因为add见名知意所以我们继续使用这个名字,那么就需要方法double add(double a, double c)。于是,add()方法就被重载了。

在Java(和C++)里,构造器是强制重载方法出现的另一个原因。构造器的名字由类名决定,那么就只能有一个构造器。但是,又想使用多种方式创建对象又该怎么办呢?那么就只有重载构造器,使得同名不同参的构造器同时存在。

重载的规则

方法重载是在一个类里面,方法名相同,而参数不同,对返回值没有强制要求可以相同也可以不同。方法重载需要注意一下几点:

  • 被重载的方法必须改变参数列表(参数个数或者类型不一样)
  • 被重载的方法介意改变返回类型和访问修饰符
  • 被重载的方法可以声明新的或者更广的检查异常
  • 方法能够在同一个类中或者在一个子类中被重载
  • 不可以返回值类型作为分区重载函数的标准

区分重载方法

每个重载的方法都有独一无二的参数类型列表。所以在区分重载方法时,只能以类名和方法的形参列表作为标准。

那为什么不能使用方法的返回值来区分呢?

比如下面两个方法,虽然它们有相同的名字和形式参数,但是却很容易区分它们

void f(){}
int f() {return 1;}

只要编译器可以根据语境明确判断出语义,比如在int x = f()中,那么的确可以根据此区分方法。不过,有时你并不关心方法的返回值,你想要的是方法调用的其他效果,这时你可能会调用方法而忽略返回值。所以,向下面这样的调用方法:

f();

此时Java该怎样判断调用的是哪个方法呢?别人也无法理解这个代码的含义。因此,依据方法的返回值来区分重载方法是行不通的。

重写(Override)

重写出现的原因

先看一个例子

class Animal{
    public void printWhoIAm(){System.out.println("Animal")}
}
public class Dog extends Animal{
    public static void main(String args[]){
        Dog dog = new Dog();
        dog.printWhoIAm();
    }
}
/*
output:
Animal
*/

当dog调用printWhoIAm()方法时,其实希望的是输出“dog”,而不是Animal。要实现输出“Dog”,想到了重载,可是重载要求被重载的方法具有不同的形参列表。这个方法不得行。dog调用的printWhoIAm()是父类中的,在子类中若是可以重写这个方法,那么就可以实现目的了。于是,重写(覆写)便产生了,为了解决父类方法在子类中不适用,而让子类重写方法的方式。我们解决以上代码需求如下:

class Animal{
    public void printWhoIAm(){System.out.println("Animal")}
}
public class Dog extends Animal{
    //加上注解@Override可以强制进行重写的检查 防止自己重写错误
    @Override
    public void printWhoIAm(){System.out.println("Dog")}
    public static void main(String args[]){
        Dog dog = new Dog();
        dog.printWhoIAm();
    }
}
/*
output:
Dog
*/

重写的规则

  • 重写是对父类允许访问的方法的实现过程进行重新编写,返回值不变或者为子类、形参列表不能改变并且访问控制权限不能严于父类。父类为default包访问权限,则子类就为public或者default;若父类是public,则子类必须为public。
  • 子类可以重写父类的除了构造器的任何方法。构造器是和类名相同的,不能被子类继承,因此也不可以被重写。
  • 重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。例如: 父类的一个方法申明了一个检查异常 IOException,但是在重写这个方法的时候不能抛出 Exception 异常,因为 Exception 是 IOException 的父类,只能抛出 IOException 的子类异常。

子类可以重写父类中访问控制权限为private的方法吗?

答案是不可以。父类中的private方法对子类来说是不可见的,就算子类中完全按照重写要求定义方法,也不能算重写父类中的方法,实际上只是子类新增的一个方法。所以,只有非private方法才可以被重写。

super.方法()和this.方法()的区别

子类若是重写了父类的方法,那么父类原来的这个方法还可以被调用吗?答案是可以的,使用super对父类的方法进行调用。

class Animal{
    public void printWhoIAm(){System.out.println("Animal")}
}
public class Dog extends Animal{
    //加上注解@Override可以强制进行重写的检查 防止自己重写错误
    @Override
    public void printWhoIAm(){System.out.println("Dog")}
    public void print(){
        super.printWhoIAm();
        printWhoIAm();// this.printWhoIAm();
    }
    public static void main(String args[]){
        Dog dog = new Dog();
        dog.print();
    }
}
/*
output:
Animal
Dog
*/

使用this.方法()会先在本类中查找是否存在要调用的方法,如果不存在则查找父类中是否具备此方法。如果有则调用,否则出现编译时错误。使用super.方法()会明确表示调用父类中的方法,直接去父类寻找要调用的方法。

重载和重写的区别

区别 重载 重写
参数列表 必须改 一定不能改
返回类型 可以修改 一定不能改
访问控制权限 可以修改 不能比父类严格
异常 可以修改 可以减少或删除,一定不能抛出新的或者更广的异常
发生范围 可以在一个类中也可以在子类中 在子类中

小结

方法的重载和重写都是Java多态性的不同表现,重载是类的多态性的表现,而重写时子类和父类的一种多态性的表现。需要再次注意的是重载和重写的定义形式。引用菜鸟教程的两句话和一张图结束。

  • 方法重载是一个类中定义了多个方法名相同,而他们的参数的数量不同或数量相同而类型和次序不同,则称为方法的重载(Overloading)。
  • 方法重写是在子类存在方法与父类的方法的名字相同,而且参数的个数与类型一样,返回值也一样的方法,就称为重写(Overriding)

参考:
《Java编程思想》第四版
菜鸟教程http://www.runoob.com/java/java-override-overload.html

原文地址:https://www.cnblogs.com/myworld7/p/10398335.html

时间: 2024-10-13 20:48:27

Java——重载和重写的相关文章

JAVA 重载,重写(覆盖)个人理解

重载,一个java类里有多个同名的方法,但参数列表不同,见下面代码: public class Caller {     /**      * 喊叫      *       * @param callMan      *            呼喊者      * @param callContent      *            呼喊内容      */     public void call(String callMan, String callContent) {        

Java重载与重写的区别

重载Overloading与重写Overriding是一个类中多态性的两种表现. (1)Java的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义. 方法重载是让类以统一的方式处理不同类型数据的一种手段. 调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法, 这就是多态性. (2) 重载的时候,方法名要一样,但是参数类型和个数不一样,返回值类型可以相同也可以不相同.无法以返回型别作为重载函数的区分标准. 下面是重载的例子:    pack

java重载和重写的区别

一.重载(Overloading) (1) 方法重载是让类以统一的方式处理不同类型数据的一种手段.多个同名函数同时存在,具有不同的参数个数/类型. 重载Overloading是一个类中多态性的一种表现. (2) Java的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义. 调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法, 这就是多态性. (3) 重载的时候,方法名要一样,但是参数类型和个数不一样,返回值类型可以相同也可以不相同.无法以

java 重载与重写 【转】

首先我们来讲讲:重载(Overloading) (1) 方法重载是让类以统一的方式处理不同类型数据的一种手段.多个同名函数同时存在,具有不同的参数个数/类型. 重载Overloading是一个类中多态性的一种表现. (2) Java的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义. 调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法, 这就是多态性. (3) 重载的时候,方法名要一样,但是参数类型和个数不一样,返回值类型可以相同也可以不

JAVA --- 重载和重写的区别

重写(Overriding) 是发生在父类和子类,接口 和 子类 之间的: 参数类型.返回类型 必须完全相同,访问级别 子类 比 父类 方法要强. 重写方法可以抛出任何非检查的异常,无论贝重写方法是否声明了该异常. 检查异常:重写方法一定不能抛出新的检查异常,或比被重写方法声明的检查异常更广的检查异常. 不能重写标为 final,static 的方法: 重载(Overloading) 参数列表:被重载的方法必须改变参数列表 返回类型:可以改变返回类型 修饰符:可以改变修饰符 异常:可以声明新的后

漫谈java重载与重写

重载(Overloading):为了让方法名相同而形参不同的构造方法同时存在,让类以统一的方式处理不同类型数据的一种手段 重写(Overriding):导出类对继承自基类的方法做出一定的修改,又称方法覆盖. 区别: 应用范围:Overloading用于同一个类的内部:Overriding用于存在继承关系的基类和导出类之间 鉴别点:Overloading  每个重载方法都有独一无二的参数类型类别(或参数类型不同,或参数个数不同,或参数顺序不同(顺序不同代码难以维护,不建议使用))         

Java重载和重写

重载:方法名一致即可,访问修饰符.返回值类型无关,然后不同的重载方法参数列表的参数的顺序,类型,数量进行变换即可. JVM通过参数列表的不同进行调度不同的方法,若参数列表相同则会出现解析错误 重写:重写方法的访问修饰符可以不同,但访问权限需要比父类中的大,比如protected修饰的方法重写的时候可以重写为public类型.返回值类型可以是父类中方法返回值类型的子类,比如父类中的方法返回Object类型,我们自己有一个类叫做Student类,然后我们在重写这个返回Object的方法时可以重写为返

Java记录 -12- 方法重载与重写

Java 重载与重写 方法重载(Overload):表示两个或多个方法名字相同,但方法参数不同.方法参数不同有两层含义:1).参数个数不同: 2).参数类型不同.注意:方法的返回值对重载没有任何影响. 构造方法重载:只需看参数即可.如果想在一个构造方法中调用另外一个构造方法,那么可以使用this()的方式调用,this()括号中的参数表示目标构造方法的参数.this()必须要作为构造方法的第一条语句.换句话说,this()之前不能有任何可执行的代码. 方法重写:

JAVA构造器,重载与重写

1. java构造器 构造器也叫构造方法(constructor), 用于对象初始化. 构造器是一个创建对象时被自动创建的特殊方法,目的是对象的初始化. 构造器 的名称与类的名称一致. JAVA通过new关键子来调用构造器,从而返回该类的实例,是一种特殊的方法. 备注要点: a. 通过new关键字来调用 b. 构造器虽然有返回值,但是不能定义返回值类型(返回值的类型是本类), 不能在构造器使用return返回某个值. c. 如果没有我们定义构造器,则编译器会自动定义一个无参构造器. 如果已定义构