【阿里云】Java面向对象开发课程笔记(十三)——覆写

    • 1 覆写
      • 1.1 方法覆写
      • 1.2 属性覆盖
      • 1.3 super关键字
    • 2 总结

1 覆写

  如果子类定义了和父类相同的方法或属性的时候,这样的操作就称为覆写。

1.1 方法覆写

  方法的覆写是的是子类定义了与父类相同的方法名称、参数类型以及个数完全相同的方法。但是被覆写的方法不能拥有比父类更高的访问控制权限: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()方法

使用覆写要关注以下两点:

  • 当前对象时通过那个类new的;
  • 当调用某一个方法,而该方法已经被子类所覆写了,则调用的一定是被覆写过的方法。

范例:错误的覆写

代码

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覆写,对吗?

  • 从概念上讲,父类方法使用了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 限制 没有权限要求 被覆写的方法不能拥有比父类更为严格的访问控制权限

  方法重载的时候返回值可以不同,但是良好的设计上要求返回类型一致。

1.2 属性覆盖

  当子类定义了与父类属性名称完全相同的属性称为属性覆盖。

代码

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封装,子类根本不知道,定义属性不要重名。

1.3 super关键字

  在子类实例化操作时,使用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.方法()一定要明确标记出是父类的操作。

2 总结

1.子类覆写父类方法是因为父类的方法功能不足,才需要覆写;
2.方法覆写的时候使用得就是public权限,将父类的方法名称直接粘贴过来。

你可能感兴趣的:(java,阿里云Java)