继承性的主要特征是子类可以根据父类已有的功能进行功能的扩展,但是在子类在定义属性或方法的时候有可能定义的属性和方法与父类同名,这样的称为覆写
方法覆写
当子类定义了与父类方法名称相同、参数的类型及个数相同的方法时,就发生了覆写
观察覆写的产生效果
class A{
public void fun(){
System.out.println("A类中的方法");
}
}
class B extends A{
}
public class testDemo{
public static void main(String args[]){
B b = new B();
b.fun();
}
}
因为这个时候子类并没有fun()方法,所以子类使用从父类继承来的的fun()方法
覆写方法
class A{
public void fun(){
System.out.println("A类中的方法");
}
}
class B extends A{
public void fun(){
System.out.println("B类中的方法");
}
}
public class testDemo{
public static void main(String args[]){
B b = new B();
b.fun();
}
}
当发生了覆写之后,此时会调用实例化子类中已经被覆写的方法
一个类可能会产生多个子类,每个子类都可能会扩展自己的方法
覆写结果的分析要素
1.观察实例化的是那个类
2.观察这个实例化的类里面调用的方法是否已经被覆写过,如果没覆写过,则调用父类的
覆写的使用原则(被动):
如果现在发现父类中的方法名称功能不足(不适合本类),但是又必须使用这个方法名称的时候,就需要采用覆写这一概念实现
以上已经实现了代码覆写的功能,但为了更好地实现覆写,还必须考虑到访问权限问题。覆写的方法不能够拥有比父类更严格的访问控制权限
对于访问控制权限已了解在三个:public > default > private
99%情况下都使用public
正确的覆写
class A{
void fun(){
System.out.println("A类中的方法");
}
}
class B extends A{
public void fun(){
System.out.println("B类中的方法");
}
}
public class testDemo{
public static void main(String args[]){
B b = new B();
b.fun();
}
}
错误的覆写
class A{
public void fun(){
System.out.println("A类中的方法");
}
}
class B extends A{
void fun(){
System.out.println("B类中的方法");
}
}
public class testDemo{
public static void main(String args[]){
B b = new B();
b.fun();
}
}
子类中使用了default权限,父类中使用了public权限,属于更加严格的范畴
此时不能称为覆写
疑问?如果父类中的方法使用了private声明,子类使用了public声明,那么叫覆写吗
从概念上来讲,父类的方法是private,属于小范围权限,而public属于扩大了范围权限。权限上符合覆写要求。
正确的覆写方法
先抛开private不看,先使用一个正常的覆写操作
class A{
public void fun(){
print();
}
public void print(){
System.out.println("A类中的方法");
}
}
class B extends A{
public void print(){
System.out.println("B类中的方法");
}
}
public class testDemo{
public static void main(String args[]){
B b = new B();
b.fun();
}
}
使用private声明父类中的方法
class A{
public void fun(){
print();
}
private void print(){
System.out.println("A类中的方法");
}
}
class B extends A{
public void print(){
System.out.println("B类中的方法");
}
}
public class testDemo{
public static void main(String args[]){
B b = new B();
b.fun();
}
}
此时发现子类中根本没有覆写print()方法,也就是说,使用了private声明,此方法对子类是不可见的,即使子类定义了一个与父类完全符合覆写要求的方法,那么也不能够发生覆写。实际上就相当于子类定义了一个新方法
默认情况下子类所能够调用的一定是被覆写过的方法。为了能够明确地由子类调用父类中已经被覆写的方法,那么可以加上"super.方法()"访问
class A{
public void fun(){
print();
}
public void print(){
System.out.println("A类中的方法");
}
}
class B extends A{
public void print(){
super.print();
System.out.println("B类中的方法");
}
}
public class testDemo{
public static void main(String args[]){
B b = new B();
b.fun();
}
}
关于super.方法()与this.方法()的区别?
使用this.方法()会首先查找本类中是否存在要调用的方法名称,存在则调用,否则查找父类中是否有此方法,有则调用,没有编译时报错
使用super.方法(),明确地表示调用的不是子类方法(不查找子类方法),直接调用父类方法
面试:请解释重载与覆写的区别?(请解释Overloading与Overwrite的区别?)
No. | 区别 | 重载 | 覆写 |
- | :-: | :-: | :-: |
1 | 英文 | Overloading | OverRide |
2 | 范围| 发生一个类里面 | 发生在继承关系中 |
3 | 定义 | 方法名称相同、参数类型及个数相同 | 方法名称相同、参数类型及个数相同、方法返回值相同 |
4 | 权限 | 重载没有权限的限制 | 被覆写的方法不能拥有比父类更严格的访问控制权限 |
在使用Overloading的时候返回值能否不同?
在发生重载关系时,返回值可以不同,但是考虑到程序设计的统一性,重载时尽量保证方法的返回值类型一致