重写和重载

重写(Override) 和 重载(Overload)

方法重写: 是一种语言特性,它是多态的具体表现,它允许子类重新定义父类中已有的方法,且子类中的方法名和参数类型及个数都必须与父类保持一致。

基本用法如下:

public class Father {
    public void Say(){
        System.out.println("Father say:");
    }
}
public class Son extends Father{
    @Override
    public void Say() {
        System.out.println("Son Say:");
    }
}
public class Main {
    public static void main(String[] args) {
        Father father = new Father();
        Son son = new Son();
        father.Say();
        son.Say();
    }
}
/*输出:
Father say:
Son Say:
*/

  重写的最经典的例子莫过于Object的equal方法,众所周知,在Java中Object是所有类的父类,所以所有的类都从Object继承下来了equal方法,用于比较两个实例对象是否相等,不过不同的类的判断相等的方法肯定不一样,所以不可能用Object类内写的equal方法来作比较,因此每个类在需要比较是否相等时,都需要自己实现自己的判断相等的逻辑,这个时候就需要在类内重写继承自Object的equal方法。

  可能这时候你就要问了,不用重写可不可以实现两个实例对象的比较呢?答案是当然可以,你大可以在自己写的类中写一个Myequal方法用于判断两个实例对象的比较。可能你又要问了,既然可以那为什么要用重写呢?这个问题其实也非常容易回答,想象一下,如果不用这种方式,而是每个类中自己实现自己的比较函数,那么就可能会出现这样一种情况:我写的类里面,用于判断相等的函数叫is;小明写的类的判断相等的函数叫xiangdeng;张三写的叫EQUAL;王五写的叫Equal。然后你用他们写的类,当你想判断是否相等的时候,你还得去翻一下文档看看他写的判断相等的函数是什么,然后再来敲代码。但是如果用重写的方式的话,那就随便拿一个类来,当你想判断是否相等时候,只需要调用equal就行了。

  当然重写的好处并不止于此,它是多态的具体表现,提供了抽象能力。

在Java中使用重写需要注意以下几点:

  • 子类方法的权限控制符不能变小,也就是如果父类方法的权限控制符是 protected,那么子类的方法权限控制符只能是 protected 或 public;
  • 子类方法返回的类型只能变小,也就是说如果父类方法返回的是 Number 类型,那么子类方法只能返回 Number 类型或 Number 类的子类 Long 类型,而不能返回 Number 类型的父类类型 Object;
  • 子类抛出异常的类型只能变小;
  • 子类方法名必须和父类方法名保持一致;
  • 子类方法的参数类型和个数必须和父类保持一致。

方法重载: 指在一个类中定义多个同名的方法,但要求每个方法具有不同的参数的类型或参数的个数。

基本用法如下:

public class Main {
    public static int add(int a,int b){
        System.out.println("int");
        return a+b;
    }
    public static double add(double a, double b){
        System.out.println("double");
        return a+b;
    }
    public static void main(String[] args) {
        System.out.println(add(1,1));
        System.out.println(add(1.0,1.0));
    }
}
/*输出:
int
2
double
2.0
*/

  遇到一个东西,首先先问问它有什么用,那么重载有什么用呢?先试想这样一个场景,需要写一套从数据库Person表里查询数据的函数,可以通过姓名查询对应的数据,可以通过年龄查询数据。

public List<Person> queryByName(String Name);
public List<Person> queryByAge(int Age);

  现在,还需要查询某一个年龄段的数据。

public List<Person> queryByAges(int from,int to);

  需要通过兴趣爱好查询数据。

public List<Person> queryByHobbies(List<Hobby> hobbies);

  需要通过年龄以及姓名查询。

public List<Person> queryByAgeAndName(int age,String Name);

  需要通过年龄以及姓名以及兴趣爱好查询。

public List<Person> queryByAgeAndNameAndHobbies(int age,String Name,List<Hobby> hobbies);

  你写好这些后,放了个假,你把工作放下,出去玩了几天,等放假结束后,你继续回到工作中,现在开始需要写客户端的代码了,这个时候你需要从通过姓名和年龄查找数据,这个时候你会调用哪个函数?queryByNameAndAge还是queryByAgeAndName?你不确定,又得去回过头看当时写的到底是什么。但是如果使用重载写呢?

public List<Person> query(String Name);
public List<Person> query(int Age);
public List<Person> query(int from,int to);
public List<Person> query(List<Hobby> hobbies);
public List<Person> query(int age,String Name);
public List<Person> query(int age,String Name,List<Hobby> hobbies);

  这样写的话是不是只需要记住一个query函数就可以进行所有的查询了呢?而且也不需要在给函数取名字的时候疯狂查字典,然后写出一个非常非常长的函数名了。

在Java中使用重载需要注意以下几点:

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

总结

  方法的重写是发生在继承关下的,子类重写父类的方法,本质上是同一个函,重写时参数类型和个数需要保持一致,返回值只能变小不能变大。而方法重载本质上是不同的函数,只是名字一样,正因如此,需要让重载的函数之间可以区分,即不能两个重载的方法参数个数和类型一致,而且返回值不能作为两个函数之间区分的标志。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值