Day34--方法的重写
override 重写
重写是方法的重写,和属性无关
示例:
创建下面三个java文件,并在A.java B.java里面创建方法,Application里面初始化A并引用test方法
A类是B类的子类
package com.liu.oop.demo05;public class A extends B{public static void test(){System.out.println("A=>test()");}
}
package com.liu.oop.demo05;public class B {public static void test(){System.out.println("B=>test()");}}
package com.liu.oop;import com.liu.oop.demo05.A;
import com.liu.oop.demo05.Person;
import com.liu.oop.demo05.Student;public class Application {public static void main(String[] args) {A a = new A();a.test();//A=>test()}
}
然后注意,操作来了
package com.liu.oop;import com.liu.oop.demo05.A;
import com.liu.oop.demo05.B;
import com.liu.oop.demo05.Person;
import com.liu.oop.demo05.Student;public class Application {public static void main(String[] args) {A a = new A();a.test();//A=>test()B b=new A();b.test();//B=>test()}
}
B b = new A ();” 在这段代码中创建了一个A
类的对象,并使用B
类型的引用变量来引用这个对象.
父类的引用可以指向子类的对象,因为子类拥有父类的所有特性并且可能还有更多的特性。例如 “B b = new A ();” 是合理的,因为 A 对象可以被视为一个特殊的 B 对象来对待。
同时,在静态方法下,B b = new A (); 方法的调用只和左边定义的数据类型有关
此时,将A、B类的方法中的ststic都去掉(必须保持一致,要去掉都去掉)
package com.liu.oop.demo05;public class A extends B{public void test(){System.out.println("A=>test()");}
}
package com.liu.oop.demo05;public class B {public void test(){System.out.println("B=>test()");}}
此时可以看到,在A编译区的左侧,有
(两个相同圆心的同心圆,右上角有一个向上的红色箭头)的图形,这是方法重写的标志
在B编译区的左侧,有
(两个相同圆心的同心圆,右下角有一个向下的黑色箭头)的图形,这是方法被重写的标志
详细解释:
以下是对这两个提示的解释:
-
“在以下位置重写方法 B(com.liu.oop.demo05)”:
- 这是针对
A
类中的public void test(){ System.out.println("A=>test()"); }
这句代码的提示。 - 意思是当前这个方法在
A
类中重写了其父类B
(位于包com.liu.oop.demo05
)中的test
方法。当一个子类定义了与父类同名、同参数列表的方法时,就被认为是重写了父类的方法。在这里,A
类继承自B
类,并且A
类中的test
方法与B
类中的test
方法具有相同的方法名和无参数的特点,所以 IDEA 识别出这是一个重写的操作,并给出这个提示,以便开发者明确知道这个方法是对父类特定方法的重写。
- 这是针对
-
“在以下位置被重写 A(com.liu.oop.demo05)”:
- 这是针对
B
类中的public void test(){ System.out.println("B=>test()"); }
这句代码的提示。 - 它表示这个方法在
B
类中定义,但在其子类A
(位于包com.liu.oop.demo05
)中被重写了。这个提示也是为了帮助开发者快速了解方法的继承和重写关系,当查看B
类的这个方法时,能立即知道它在哪个子类中被重写了。
- 这是针对
方法重写只和非静态有关
此时,我们可以将A里面的方法删除,然后用Alt+Insert---->方法重写
package com.liu.oop.demo05;public class A extends B{@Overridepublic void test() {super.test();}
}
其中,@Override 是注解;有功能的注释
super.test(); 默认调用父类的方法,我们也可以改为自己的内容
package com.liu.oop.demo05;public class A extends B{@Override //注解;有功能的注释public void test() {System.out.println("A=>test()");}
}
但是,这时候Application的输出结果发生改变
package com.liu.oop;import com.liu.oop.demo05.A;
import com.liu.oop.demo05.B;
import com.liu.oop.demo05.Person;
import com.liu.oop.demo05.Student;public class Application {public static void main(String[] args) {A a = new A();a.test();//A=>test()//父类的引用指向了子类B b=new A();b.test();//A=>test()}
}
可见,静态方法和非静态方法差别很大!!!!!!!!!!!!!!!
再将A B里面方法的public改成private
package com.liu.oop.demo05;public class A extends B{private void test() {System.out.println("A=>test()");}
}
package com.liu.oop.demo05;public class B {private void test(){System.out.println("B=>test()");}}
在装订线附近,没有了方法重写的图标了
可见,方法重写的前提之一是在public公开
总结:
重写:需要有继承关系,子类重写父类的方法!
-
方法名必须相同。
-
参数列表必须相同。
-
修饰符:范围可以扩大。比如,父类的方法修饰符是private,子类可以是范围更大的public。但是,反过来不行
范围大小:public> Protected > Default > private
-
抛出的异常,可以被缩小,不能被扩大