一、方法覆盖Override
1、什么时候使用Override
例如:以下代码:鸟儿在执行move方法时,最好输出“鸟儿在飞翔”,但是当前程序在执行move方法时,输出“动物在移动”,显然Bird子类继承来的方法无法满足需求
子类继承父类之后,当继承过来的方法无法满足当前子类的业务需求时,子类有权利进行重新编写方法
public class OverrideTest{
public static void main(String[] args){
Bird b = new Bird();
b.move();
Cat c = new Cat();
c.move();
}
}
// 父类
class Animal{
public void move(){
System.out.println("动物在移动");
}
// protected表示受保护的,没有public开放
protected void eat(){
System.out.println("动物在吃");
}
}
// 子类
class Bird extends Animal{
// 子类继承父类之后,有一些行为可能需要进行改进
// move重写
public void move(){
System.out.println("鸟儿在飞翔");
}
/*
错误:正在城市分配更低的访问权限,以前为public
protected void move(){
System.out.println("鸟儿在飞翔");
}
*/
// 可以更高
public void eat(){
System.out.println("鸟儿在抓虫子吃");
}
public void sing(){
System.out.println("鸟儿在唱歌");
}
}
class Cat extends Animal{
public void move(){
System.out.println("猫猫在走路");
}
public void catchMouse(){
System.out.println("猫猫抓老鼠");
}
}
2、结论
当子类堆父类继承过来的方法进行“方法覆盖”之后,子类对象调用该方法的时候,一定执行覆盖之后的方法
3、构成方法覆盖的条件
条件1:两个类必须有继承关系
条件2:重写之后的方法和之前的方法具有:相同的方法名、相同的形参列表、相同的返回值类型
注意:相同的返回值类型:对于返回值类型是基本数据类型,必须一致
对于返回值类型是引用数据类型,可以变小,但意义不大,不会这样写
条件3:访问权限不能更低,可以更高
条件4:重写之后的方法不能比之前的方法抛出更多的异常,可以更少
注意事项:注意1:方法覆盖只是针对于方法,和属性无关
注意2:私有方法无法覆盖
注意3:构造方法不能被继承,所以构造方法也不能被覆盖
注意4:方法覆盖只是针对于实例方法,静态方法覆盖没有意义
4、解释:方法覆盖只是针对于实例方法,静态方法覆盖没有意义
方法覆盖只针对实例方法,静态方法覆盖没有意义
/*
1、
没有多态机制,方法覆盖可有可无
没有多态机制,方法覆盖也可以没有,如果无法满足子类业务需求时,子类完全可以重新定义一个新方法
2、静态方法存在方法覆盖么?
多态自然和对象有关系
但是静态一般和对象没有关系
所以一般情况下,我们会说“静态方法”没有方法覆盖
*/
public class OverrideTest05{
public static void main(String[] args){
Animal a = new Cat();
a.doSome();// 输出:Animal的doSome方法
Animal.doSome();
Cat.doSome();
}
}
class Animal{
public static void doSome(){
System.out.println("Animal的doSome方法");
}
}
class Cat extends Animal{
// 尝试覆盖
public static void doSome(){
System.out.println("Cat的doSome方法");
}
}
5、解释:私有方法无法覆盖
在外部类无法访问私有的
二、多态
1、向上转型与向下转型
1)向上转型
子----->父(可以这样叫自动类型转换)
2)向下转型
父----->子(可以这样叫强制类型转换,需要加强制类型转换符)
因为自动类型转换和强制类型转换是基本数据类型之间,向上转型和向上转型是在引用类型之间
注意:java中允许向上转型也允许向下转型,但是无论哪种,两种类型之间必须有继承关系,没有继承关系编译器会报错
2、什么时候使用向下转型
不要随便使用强制类型转换
当你需要访问的是子类对象中“特有”的方法,此时需要向下转型
3、多态的基础语法
父类型引用指向子类型对象
包括编译阶段和运行阶段。编译阶段:绑定父类方法,运行阶段:动态绑定子类方法
public class Test01{
public static void main(String[] args){
Animal a1 = new Animal();
a1.move();
Cat c = new Cat();
c.move();
Bird b = new Bird();
b.move();
/*
父类型的引用允许指向子类型的对象
允许a2这个父类型引用指向子类型的对象
*/
Animal a2 = new Cat();
Animal a3 = new Bird();
/*
什么是多态
分析a2.move();
java程序分为编译阶段和运行阶段
编译阶段:
编译器只知道a2的类型是Animal,所以编译器在检查语法的时候会去Animal.class字节码文件中找move方法
找到之后,绑定上move方法,编译通过,静态绑定成功(编译阶段属于静态绑定)
运行阶段:
实际上在堆内存中创建的java对象是Cat对象,所以在move时,真正参与move的对象是Cat,
所以运行阶段会动态执行Cat对象的move方法,这个过程属于运行阶段绑定(运行阶段绑定属于动态绑定)
多态表示多种形态:
编译的时候时一种形态,运行的时候是一种形态
*/
a2.move();// 猫猫在走路
a3.move();// 鸟儿在飞翔
Animal a5 = new Cat();
// 分析程序一定要分析静态绑定和动态绑定
// 编译不能通过,报错,编译器只知道a5是Animal类型,去Animal.class中找catchMouse没找到
// a5.catchMouse();
// 如果a5非要使用catchMouse方法,就需要使用向下转型
// 什么时候使用向下转型:这个行为是子类型对象特有的方法
Cat x = (Cat)a5;// 强制转换为Cat类型
x.catchMouse();
}
}
4、向下转型有风险,怎样避免
/*
编译不会报错
但是运行报错
因为在运行阶段,堆内存中实际存放的Bird对象,但是又强制转成Cat,Bird与Cat没有继承关系
*/
Animal a6 = new Bird();
Cat y = (Cat)a6;
y.catchMouse();
1)避免向下转型风险
Java规范中要求:任何时候对类型进行向下转型时,一定要先使用instanceof运算符进行判断
// 怎样避免ClassCastException异常 类转换异常发生
/*
运算符 instanceof
第一:instanceof可以在运行阶段动态判断引用指向的对象的类型
第二:instanceof语法
(引用 instanceof 类型)
第三:instanceof运算符的运算结果只能是true、false
第四:c是一个引用,c变量保存了内存地址指向了堆中的对象
假设(c instanceof Cat)为true表示:c引用指向的堆内存中的java对象是一个Cat
假设(c instanceof Cat)为true表示:c引用指向的堆内存中的java对象不是是一个Cat
*/
Animal a6 = new Bird();
if (a6 instanceof Cat){// 如果a6是Cat,在强制类型转换
Cat y = (Cat)a6;
y.catchMouse();
}
2)为什么要用instanceof判断
/*
明明可以看到new的是谁,为什么还要判断呢
原因是:有可能以后肉眼看不到
*/
Animal x = new Bird();
Animal y = new Cat();
if(x instanceof Bird){
Bird b = (Bird)x;
b.sing();
}else if(x instanceof Cat){
Cat c = (Cat)x;
c.catchMouse();
}
if(y instanceof Bird){
Bird b = (Bird)y;
b.sing();
}else if(y instanceof Cat){
Cat c = (Cat)y;
}
class AnimalTest{
public void test(Animal a){
// 别人调用时调用test方法时传参数是穿一个Bird还是Cat
// 别人不知道要传过来一个什么
// Cat c = (Cat)a;
// c.catchMouse();
if(x instanceof Bird){
Bird b = (Bird)a;
b.sing();
}else if(x instanceof Cat){
Cat c = (Cat)a;
c.catchMouse();
}
}
}
标签:--,move,多态,Cat,public,Animal,JavaSE,方法,Bird From: https://www.cnblogs.com/hyy-0/p/17609773.html