java中的重写与重载_java中的重写与重载

1.重写

重写(Override)是父类与子类之间的多态性,实质是对父类的函数进行重新定义,如果在子类中定义某方法与其父类有相同的名称和参数则该方法被重写,不过子类函数的访问修饰权限不能小于父类的;若子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数表,则新方法将覆盖原有的方法,如需父类中原有的方法则可使用 super 关键字。

重写的规则:参数列表必须完全与被重写的方法相同,否则不能称其为重写;返回类型必须一直与被重写的方法相同,否则不能称其为重写;访问修饰符的限制一定要大于等于被重写方法的访问修饰符;重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常,譬如父类方法声明了一个检查异常 IOException,在重写这个方法时就不能抛出 Exception,只能抛出 IOException 的子类异常,可以抛出非检查异常。

1 packageFinalDemo;2

3 //父类

4 public classAnimal {5

6 String name;7 intno;8 public voideat(){9 System.out.println("动物会吃饭");10 }11

12 }

1 packageFinalDemo;2

3 //子类

4 public class Cat extendsAnimal{5

6 public static voidmain(String[] args){7

8 Cat c=newCat();9 c.eat();10

11 }12

13 /*

14 * 重写父类的eat()方法15 */

16 public voideat(){17 super.eat(); //如果需要保留父类中的方法,采用:super.方法名 的格式调用

18 System.out.println("白猫会吃饭");19 }20 }

运行结果:

3dc4217503eb5847688127959492a444.png

1.1 toString()方法的重写

(1)不重写

packageFinalDemo;public classAnimal {

String name;intno;

String gender;

Animal(String name,intno,String gender){this.name=name;this.no=no;this.gender=gender;

}public static voidmain(String[] args){

Animal a=new Animal("动物",1,"M");

System.out.println(a.toString());//没有重写toString()方法

}

}

运行结果:

19752121a57ee553c53ff7491870c91d.png

(2)重写toString()方法

61b37a04046495b1af8769aa971abbff.png

运行结果:

e2b1880408e326fab29218a1a098cde0.png

1.2 equals()方法的重写

(1)不重写

1 packageFinalDemo;2

3 public classAnimal {4

5 String name;6 intno;7 String gender;8

9 Animal(String name,intno,String gender){10 this.name=name;11 this.no=no;12 this.gender=gender;13 }14

15

16 public static voidmain(String[] args){17 Animal a=new Animal("动物",1,"M");18 Animal b=new Animal("动物",1,"M");19

20 System.out.println(a.equals(b));21 }22

23 }

运行结果:

false

分析为什么为false呢?

而:

1 String a1="小狗";2 String b1="小狗";3 System.out.println(a1.equals(b1));

运行结果是:true

原因分析:

equals()在java.lang.Object下,而在Object中,equals()方法只是判断两者是否为同一个对象的引用,如下图所示:

e7446d174c528202cf946cb484dcb058.png

而在String类中,对equals()方法进行了重写:

82ac3f271d2ea3acd869124c64c071ef.png

所以输出的是true

(2)重写:

1 packageFinalDemo;2

3 public classAnimal {4

5 String name;6 intno;7 String gender;8

9 Animal(String name,intno,String gender){10 this.name=name;11 this.no=no;12 this.gender=gender;13 }14

15 //重写hashCode()

16 @Override17 public inthashCode() {18 final int prime = 31;19 int result = 1;20 result = prime * result + ((gender == null) ? 0: gender.hashCode());21 result = prime * result + ((name == null) ? 0: name.hashCode());22 result = prime * result +no;23 returnresult;24 }25

26

27 //重写equals()

28 @Override29 public booleanequals(Object obj) {30 if (this ==obj)31 return true;32 if (obj == null)33 return false;34 if (getClass() !=obj.getClass())35 return false;36 Animal other =(Animal) obj;37 if (gender == null) {38 if (other.gender != null)39 return false;40 } else if (!gender.equals(other.gender))41 return false;42 if (name == null) {43 if (other.name != null)44 return false;45 } else if (!name.equals(other.name))46 return false;47 if (no !=other.no)48 return false;49 return true;50 }51

52 public static voidmain(String[] args){53 Animal a=new Animal("动物",1,"M");54 Animal b=new Animal("动物",1,"M");55 String a1="小狗";56 String b1="小狗";57 //System.out.println(a1.equals(b1));

58 System.out.println(a.equals(b));59 }60

61 }

运行结果:

true

结果分析:

为什么要重写hashCode()?

因为比较时,首先比较两者的hash值,若两者的hash值不同,那么两者肯定不同,所以无需进行equals()比较,而当两者的hash值相同时,再进行equals()比较。这样做,首先会节省时间,其次,若不进行hash()的重写,会产生一下这样情况:

1 packageFinalDemo;2

3 public classAnimal {4

5 String name;6 intno;7 String gender;8

9 Animal(String name,intno,String gender){10 this.name=name;11 this.no=no;12 this.gender=gender;13 }14

15

16

17 //重写equals()

18 @Override19 public booleanequals(Object obj) {20 if (this ==obj)21 return true;22 if (obj == null)23 return false;24 if (getClass() !=obj.getClass())25 return false;26 Animal other =(Animal) obj;27 if (gender == null) {28 if (other.gender != null)29 return false;30 } else if (!gender.equals(other.gender))31 return false;32 if (name == null) {33 if (other.name != null)34 return false;35 } else if (!name.equals(other.name))36 return false;37 if (no !=other.no)38 return false;39 return true;40 }41

42 public static voidmain(String[] args){43 Animal a=new Animal("动物",1,"M");44 Animal b=new Animal("动物",1,"M");45 //String a1="小狗";46 //String b1="小狗";47 //System.out.println(a1.equals(b1));

48 System.out.println("a的hash值:"+a.hashCode());49 System.out.println("b的hash值:"+b.hashCode());50 System.out.println(a.equals(b));51 }52

53 }

结果:

aa48f0caa3b769642a3136288ba1a61e.png

可以看到,两者的hash值不同,但是用equals()判定的返回值确实ture,这部满足之前的要求,即hash值不同,equals为false,至于为什么这里出现了两者的hash值不同,而equals判定为true,我也不清楚,后面再查资料解决。

所以修改为:

1 packageFinalDemo;2

3 public classAnimal {4

5 String name;6 intno;7 String gender;8

9 Animal(String name,intno,String gender){10 this.name=name;11 this.no=no;12 this.gender=gender;13 }14

15

16

17

18 //重写hash方法

19 @Override20 public inthashCode() {21 final int prime = 31;22 int result = 1;23 result = prime * result + ((gender == null) ? 0: gender.hashCode());24 result = prime * result + ((name == null) ? 0: name.hashCode());25 result = prime * result +no;26 returnresult;27 }28

29 //重写equals方法

30 @Override31 public booleanequals(Object obj) {32 if (this ==obj)33 return true;34 if (obj == null)35 return false;36 if (getClass() !=obj.getClass())37 return false;38 Animal other =(Animal) obj;39 if (gender == null) {40 if (other.gender != null)41 return false;42 } else if (!gender.equals(other.gender))43 return false;44 if (name == null) {45 if (other.name != null)46 return false;47 } else if (!name.equals(other.name))48 return false;49 if (no !=other.no)50 return false;51 return true;52 }53

54 public static voidmain(String[] args){55 Animal a=new Animal("动物",1,"M");56 Animal b=new Animal("动物",1,"M");57 //String a1="小狗";58 //String b1="小狗";59 //System.out.println(a1.equals(b1));

60 System.out.println("a的hash值:"+a.hashCode());61 System.out.println("b的hash值:"+b.hashCode());62 System.out.println(a.equals(b));63 }64

65 }

运行结果:

4f757152b753cd451322ec05652ea759.png

可以看到,重写了hash方法和equals方法后,两者的hash值相同了,equals判定的返回值也为true.

2. 重载

重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。

最常用的地方就是构造器的重载。

2.1 重载规则

被重载的方法必须改变参数列表(参数个数或类型不一样);

被重载的方法可以改变返回类型;

被重载的方法可以改变访问修饰符;

被重载的方法可以声明新的或更广的检查异常;

方法能够在同一个类中或者在一个子类中被重载。

无法以返回值类型作为重载函数的区分标准。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值