欢迎访问宙启技术站
智能推送

Java中函数的覆盖(override)是什么?如何正确使用?

发布时间:2023-10-24 16:58:28

Java中的函数覆盖(override)是指子类重写父类的方法。子类可以通过覆盖父类方法来改变方法的实现细节,以满足自己的需求。这样做的目的是为了实现多态性,使得不同的子类对象可以根据自己的实际类型调用相同的方法。

要正确使用函数覆盖,需要满足以下几个条件:

1. 函数覆盖只能发生在子类与父类之间。子类必须继承父类,并且新定义的方法与父类方法具有相同的名称、返回类型和参数列表。

2. 子类覆盖父类方法时,访问权限不能更低。子类的访问权限要么与父类相同,要么更高。

3. 被覆盖的父类方法不能是final或static修饰的。final修饰的方法无法被子类继承或重写,static修饰的方法属于类级别,而不是实例级别,无法多态调用。

4. 被覆盖的父类方法必须被子类方法完全重写,即方法名、参数个数、参数类型和返回值类型都完全相同。如果不同,则不是覆盖,而是重载。

5. 子类可以选择性地抛出异常。如果父类方法声明了异常,子类可以选择不抛出异常;如果父类方法没有声明异常,子类也可以选择抛出异常。但是,子类抛出的异常类型必须是父类声明异常的子类型。

正确使用函数覆盖的示例代码如下:

class Animal {
    public void makeSound() {
        System.out.println("Animal makes sound");
    }
}

class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Cat makes meow sound");
    }
}

class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Dog makes bark sound");
    }

    public void catchBall() {
        System.out.println("Dog catches the ball");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal1 = new Animal();
        Animal animal2 = new Cat();
        Animal animal3 = new Dog();

        animal1.makeSound(); // Output: Animal makes sound
        animal2.makeSound(); // Output: Cat makes meow sound
        animal3.makeSound(); // Output: Dog makes bark sound

        // animal2.catchBall(); // Compilation error: Animal does not have catchBall() method
        ((Dog) animal3).catchBall(); // Output: Dog catches the ball
    }
}

在上面的代码中,Animal类是父类,它有一个makeSound()方法。Cat类和Dog类继承自Animal类,并分别重写了makeSound()方法。在main方法中,通过父类引用指向不同的子类对象,并调用makeSound()方法。可以看到,即使是相同的方法名,不同的子类对象调用后输出不同的结果,这就是多态的体现。

需要注意的是,animal2无法调用catchBall()方法,因为它是通过父类引用指向子类对象的,编译器只能识别出它是Animal对象,没有catchBall()方法。如果要调用Dog类特有的方法,可以通过强制类型转换将animal3转换为Dog类型,然后再调用特有方法。