如果子类定义了和父类相同的方法或属性的时候,这样的操作就称为覆写。
方法的覆写是的是子类定义了与父类相同的方法名称、参数类型以及个数完全相同的方法。但是被覆写的方法不能拥有比父类更高的访问控制权限:private > default > public。
范例:观察一个简单覆写
代码
class Person {
public void printInfo(){
System.out.println("1.【Person类】printInfo()方法");
}
}
class Student extends Person{ // 定义了一个子类
// 一般情况下子类中的方法名称与父类中的方法名称完全一样
public void printInfo(){
System.out.println("2.【Student类】printInfo()方法");
}
}
public class TestDemo {
public static void main( String[] args ){
Student stu = new Student();
stu.printInfo();
}
} // 输出:2.【Student类】printInfo()方法
使用覆写要关注以下两点:
范例:错误的覆写
代码
class Person {
public void printInfo(){
System.out.println("1.【Person类】printInfo()方法");
}
}
class Student extends Person{ // 定义了一个子类
void printInfo(){ // 权限更加严格
System.out.println("2.【Student类】printInfo()方法");
}
}
结论:以后写方法,就写public,写属性,98%写private。
问题:如果父类方法使用了private,子类使用了public覆写,对吗?
代码
class Person {
public void fun(){
this.printInfo();
}
// 父类方法使用了private,那么就表示该方法只能够被父类所使用,子类无法使用,也就是说子类不知道父类有该方法。
private void printInfo(){
System.out.println("1.【Person类】printInfo()方法");
}
}
class Student extends Person{ // 定义了一个子类
// 这时该方法只是子类定义的新方法而已,和父类的方法没有关系。
public void printInfo(){
System.out.println("2.【Student类】printInfo()方法");
}
}
public class TestDemo {
public static void main( String[] args ){
Student stu = new Student();
stu.fun();
}
}
输出结果:
1.【Person类】printInfo()方法
面试题:请解释重载与覆写的区别?在进行重载时返回值是否可以不同?
序号 | 项目 | 重载 | 覆写 |
---|---|---|---|
No.1 | 英文单词 | OverLoading | Override |
No.2 | 概念 | 方法名称相同,参数的类型及个数不同 | 方法名称、参数类型及个数都相同 |
No.3 | 范围 | 发生在一个类之中 | 发生在继承关系当中 |
No.4 | 限制 | 没有权限要求 | 被覆写的方法不能拥有比父类更为严格的访问控制权限 |
方法重载的时候返回值可以不同,但是良好的设计上要求返回类型一致。
当子类定义了与父类属性名称完全相同的属性称为属性覆盖。
代码
class Person {
public String info = "www";
}
class Student extends Person{
// 因为此时按照就近取用的原则,肯定找被覆盖的属性名称
public int info = 100;
public void printInfo(){
System.out.println(info);
}
}
public class TestDemo {
public static void main( String[] args ){
Student stu = new Student();
stu.printInfo();
}
} // 输出结果:100
这种操作没有意义,因为属性都要求private封装,子类根本不知道,定义属性不要重名。
在子类实例化操作时,使用super()调用父类构造方法。
在覆写的操作中,子类可以使用super.方法()、super.属性,明确调用父类的方法或属性。
范例:观察一个程序
class Person {
public void printInfo(){
System.out.println("1111111111111111");
}
}
class Student extends Person{
public void printInfo(){
// this.printInfo;
super.printInfo();
System.out.println("2222222222222222");
}
}
public class TestDemo {
public static void main( String[] args ){
Student stu = new Student();
stu.printInfo();
}
}
输出结果
1111111111111111
2222222222222222
如果此时写上了“this.printInfo()”操作,那么就表示先从本类查找所需要的方法,如果本类没有,则去找父类的方法进行调用。而如果是“super.printInfo()”,表示的是不查找本类而直接调用父类中的方法。
子类调用父类方法是一定要加super
范例:调用父类属性
代码
class Person {
public String info = "www";
}
class Student extends Person{
public int info = 100;
public void printInfo(){
// 不找本类属性,直接找父类中的属性
System.out.println(super.info);
System.out.println(this.info);
}
}
public class TestDemo {
public static void main( String[] args ){
Student stu = new Student();
stu.printInfo();
}
}
输出结果
www
100
super是子类访问父类的处理操作,this是本类的访问处理操作。
序号 | 项目 | this | super |
---|---|---|---|
No.1 | 概念 | 访问本类中的属性、方法 | 由子类访问父类中的属性或方法 |
No.2 | 查找范围 | 先查找本类,如果本类没有则调用父类 | 不查找本类而直接调用父类定义 |
No.3 | 特殊 | 表示当前对象 | 无 |
能使用super.方法()一定要明确标记出是父类的操作。
1.子类覆写父类方法是因为父类的方法功能不足,才需要覆写;
2.方法覆写的时候使用得就是public权限,将父类的方法名称直接粘贴过来。