方法的重写(覆盖)

重写:子类继承父类后,可以对父类中同名同参数的方法进行覆盖操作。重写以后,当创建子类对象以后,通过子类对象调用父类中的同名同参数方法时,实际执行的是子类重写父类的方法。

一般的,我们称子类叫重写的方法,父类的叫被重写的方法。

注意:构造函数不是成员,因此它们不会被子类继承,但是可以从子类调用超类的构造函数。

package com.studyjava.unit1;

class Person
{
    private String name;
    private int age;

    public Person ()
    {
        name = "";
        age = 0;
    }

    public Person (String name, int age)
    {
        this.name = name;
        this.age = age;
    }

    public String getName ()
    {
        return name;
    }

    public int getAge ()
    {
        return age;
    }

    public void setName (String name)
    {
        this.name = name;
    }

    public void setAge (int age)
    {
        this.age = age;
    }

    public void job()
    {
        System.out.println("no job");
    }
}

class Worker extends Person
{
    public Worker ()
    {
        super();
    }
    public Worker (String name, int age)
    {
        super(name, age);
    }

    public void job ()
    {
        System.out.println("I work as a worker.");
    }
}

public class T9
{
    public static void main (String[] args)
    {
        var worker = new Worker("durant", 32);
        worker.job();  // I work as a worker
    }
}

重写规则

规则1

子类重写方法的方法名和形参列表与父类中被重写的方法名、形参列表一致。这个很好理解,如果方法名一致,但形参不一致,那就不是重写而是重载了。

规则2

子类重写的方法的权限修饰符不能小于父类的。比如,上述的Person中job方法是public,那么子类就只能是public。如果父类是protected,那么子类可以是protected或public。否则,编译 不通过。

注意,这里有一个特殊的情况。父类方法如果是private,那么子类不可以重写该方法。可以这样理解,父类的private方法,在子类当中是不可见的,子类不知道父类有该方法,所以就不存在重写一说。

如果父类中有一个private的show方法,子类写了一个public的show方法。那么,这种情况时可以编译通过的,但不属于重写。

class Parent
{
    private void show ()
    {
        System.out.println("say hello");
    }
}

class Child extends Parent
{
    public void show ()
    {
        System.out.println("say nothing");
    }
}

上述代码能够编译通过。这里,我们再来证明下是上述不是重写。

class Parent
{
    private void show ()
    {
        System.out.println("say hello");
    }

    public void print ()
    {
        System.out.print("----------");
        show();
    }
}

class Child extends Parent
{
    public void show ()
    {
        System.out.println("say nothing");
    }
}

下面是测试代码

var child = new Child();
child.print();  //----------say hello 

如果是重写的话,则打印 //----------say nothing。所以证明了,该情况不是重写。

规则3

返回值类型要求,有以下几种情况

  • 父类被重写的方法返回值类型为void,则子类只能是void
  • 父类A类型,子类A类型或A类的子类
  • 父类为基本数据类型,子类也只能是同样的基本数据类型

规则4

子类方法抛出的异常不能大于父类被重写方法的异常