方法的重写与多态
方法的重写
方法重写也叫方法覆盖,是指子类根据需求对从父类继承的方法进行重新编写。通常父类的方法被子类继承后,在不同的子类中可能需要做不同的操作。方法只能在子类中进行重写。
重写时,可以用super.方法的方式来保留父类的方法。但构造方法不能被重写,因为子类不能从父类中继承父类构造方法,而是调用父类的构造方法。
方法重写的规则
方法重写的规则有以下几点:
1、方法名相同
2、参数类型相同
3、返回值类型相同或是其子类(不能是基本数据类型的自动转换)
4、访问权限不能严于父类(子类中方法的访问修饰符所限定的范围必须大于或等于父类的)
5、父类的静态方法不能被子类覆盖为非静态方法,父类的非静态方法不能被子类覆盖为静态方法
6、子类可以定义与父类同名的静态方法,以便在子类中隐藏父类的静态方法(静态方法中无法使用super和this)
7、父类的私有方法不能被子类覆盖
8、不能抛出比父类方法更多的异常
方法重载与方法重写的区别
| 比较项 | 位置 | 方法名 | 参数列表 | 返回值 | 访问修饰符 |
|---|---|---|---|---|---|
| 方法重写 | 子类 | 相同 | 相同 | 相同或是其子类 | 不能比父类更严格 |
| 方法重载 | 同类 | 相同 | 相同 | 无关 | 无关 |
方法重载是在同一个类中对一个方法进行重载,
而方法重写是在子类中对父类的方法进行重新编写。
Object类
在Java中,Object类是所有类的直接或间接父类。
Object类中被子类经常重写的方法
| 方法 | 说明 |
|---|---|
| toString() | 返回当前对象本身的有关信息,按字符串对象返回 |
| equals() | 比较两个对象是否是同一个对象,是则返回true |
| hashCode() | 返回该对象的哈希代码值 |
| getClass() | 获取当前对象所属的类信息,返回Class对象 |
其中用的最多的是equals()方法
Object类中的equals()方法
比较两个对象是否是同一个对象,是则返回true。
操作符==的用法:
(1)简单数据类型,直接比较值。如1==2
(2)引用类型,比较两者是否为同一对象
equals:
(1)Object类中的equals()方法与==没区别(都是比较两个对象的内存地址)
(2)当有特殊需求,如认为属性相同即为同一对象时,需要重写equals()
(3)Java.lang.String 重写了equals()方法,把equals()方法的判断变为了判断其值
多态
在现实中,同一种事物,由于条件不同,产生的结果也不同。如黑白打印机和彩色打印机打印出来的效果不同。在Java中,多态是指同一个引用类型,使用不同的实例而执行不同的操作。方法重写是实现多态的基础。
实现多态的要素:
1、子类重写父类的方法。
2、用父类引用指向子类对象
在多态中,还涉及到一些概念:
抽象类
在现实中,我们可以明确一只狗,或者一只猫,但是我们不知道一只宠物指的是什么,相对于猫和狗而言,宠物是猫和狗的一个统称,在java中,宠物是猫和狗的一个父类,而类似这种父类,通常无法进行实例化,我们把它定义为抽象类,用关键字abstract来修饰类名。
抽象类没有具体的实例,不能被实例化。但是可以创建一个引用变量,其类型是一个抽象类,指向非抽象的子类实例。抽象类不能是最终类。因为抽象类是用来被继承的,而最终类是无法被继承的,互相就矛盾了。
抽象类的作用:
1、抽象类定义了一种父类型,用来被继承。而子类可抽象可不抽象,不抽象的子类可以new实例化。
2、抽象类中的抽象方法没有无需写方法体,而通过子类来实现这个方法,能够减少一些代码量。
抽象方法
类中有些方法没有实现代码,也不能有实现代码,这样的方法可以定义为抽象方法。Java中抽象方法用abstract修饰方法名。
语法:
abstract 返回值类型 方法名(参数列表);
抽象方法需要注意以下几点:
1、抽象方法没有方法体(没有{})
2、抽象方法必须在抽象类里
3、抽象方法必须在子类中被实现,除非子类是抽象类
抽象类和抽象方法之间的关系:
1、一个类中只要有一个抽象方法,这个类就必须是抽象类
2、一个抽象类里不一定要有抽象方法
3、抽象方法必须被非抽象的子类实现(通过重写),否则子类依然必须是抽象类
4、没有抽象的构造方法,也没有抽象静态方法
5、抽象类中可以有非抽象的构造方法,创建子类的实例时可以调用。
对象的类型转换
对象间的类型转换要求两种类型之间必须有继承关系,无任何继承关系的类型之间是不能转换的。
1、向上转型
父类的引用指向子类对象,自动(隐式)进行类型转换(子类类型转父类类型)。
如:Pet pet =new Dog();
语法:
<父类型><引用变量名> = new <子类型>();
此时通过父类引用变量调用的方法是子类覆盖或继承父类的方法,不是父类的方法。
任何类型都可转为Object类。
2、向下转型
将一个指向子类对象的父类引用赋给一个子类的引用,即父类类型转换为子类类型,需要强制转换。
如:Dog dog = (Dog)pet;
语法:
<子类型><引用变量名>=(<子类型>)<夫类型引用变量>;
向下转型必须满足:
1、父类型所指向的对象确实是该子类型的对象。
2、向下转型前应该用instanceof进行判断是不是子类型的对象。
在向下转型的过程中,如果没有转换为真实子类类型,会出现类型转换异常,Java中提供了instanceof运算符来进行类型的判断。
instanceof运算符
在向下转型前,通过instanceof来判断对象类型是否和所转类型之间有继承的上下级关系。
使用instanceof时,对象的类型必须和instanceof后面的参数所指定的类在继承上有上下级关系。
instanceof运算符是判断某一引用类型所引用的某一对象是否属于某一种类型。
语法:
<对象名> instanceof <类名>
其运算结果为布尔值。
如:obj instanceof Student
多态的经典应用场合
以下以父类Goods类,子类Tvs类和Foods类为例
(1)父类类型作为方法的形参实现多态
public void print(Goods g) {
if(g instanceof Tvs) {
((Tvs)g).price();
}else if(g instanceof Foods) {
((Foods)g).price();
}
}
(2)父类类型作为方法的返回值实现多态
public Goods getGoods(int type) {
if(type==1) {
return new Tvs(2999);
}else if(type==2) {
return new Foods(5.0f);
}
return null;
}
使用多态的好处:
1、减少代码量
2、提高代码的可拓展性和可维护性
本文详细介绍了Java中的方法重写规则,包括如何重写父类方法,以及重写与重载的区别。此外,还探讨了Object类中的equals()方法。接着,文章深入讨论了多态的概念,包括抽象类、抽象方法、对象类型转换,以及多态的经典应用场合,如使用父类类型作为方法的形参和返回值。
584

被折叠的 条评论
为什么被折叠?



