📜  final 方法和抽象方法 (1)

📅  最后修改于: 2023-12-03 15:00:45.427000             🧑  作者: Mango

Final方法和抽象方法

在Java中,final和abstract是两个相互矛盾的关键词,前者表示最终的、不可改变的,后者表示未定的、需要子类继承并实现的,它们分别用于方法的定义时,有着不同的语义。

final方法

final方法是指该方法不可以被子类覆盖(即override),一旦被声明为final方法,它不可以再被子类改变。

声明final关键字的方法有以下特点:

  • final方法可以被继承,但是不能被修改,即方法体不能被重写。

  • final方法可以被重载,即可以有相同名称的final方法,参数列表可以不同。

  • final方法的调用速度相对于普通的方法要快,因为编译器会在编译期间将final方法调用转换为静态绑定,即在编译器就能确定所调用的方法。

下面是一个使用final方法的示例代码:

public class Animal {
    public final void eat() {
        System.out.println("Animal is eating...");
    }
}

public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("Cat is eating...");
    }
}

在上面的代码中,Animal类中的eat方法被定义为final方法,子类Cat继承Animal类并试图覆盖eat方法,但是编译器会提示"Cannot override the final method from Animal",因为被final声明的方法不可被改变。

抽象方法

抽象方法是指只有方法声明,没有方法体,需要子类去实现的方法。可以将一个类声明为抽象类,如果一个类包含抽象方法,那么该类必须声明为抽象类。抽象方法不能被直接调用,只有在子类中实现后才能被调用。

抽象方法的声明方式如下所示:

public abstract void methodName(parameters);

以下是Java中抽象方法的示例代码:

public abstract class Vehicle {
    public abstract void accelerate();
}

public class Car extends Vehicle {
    @Override
    public void accelerate() {
        System.out.println("Car is accelerating...");
    }
}

public class TestVehicle {
    public static void main(String[] args) {
        Car car = new Car();
        car.accelerate();
    }
}

在上面的代码中,Vehicle类中定义了一个抽象方法accelerate(),该方法只有声明,没有方法体。Car类继承Vehicle类并实现了该抽象方法,main方法中创建了一个Car对象并调用其accelerate()方法。

抽象类和final方法的结合使用

抽象类可以包含final方法,这意味着子类不能覆盖该方法,但是,abstract类中一般不定义final方法,因为抽象类的目的是为了让子类继承和实现其中的抽象方法,final方法不具备可以被覆盖的特点,与抽象类的目的相违背。

下面是一个抽象类中定义final方法的示例代码:

public abstract class Shape {
    public abstract double area();
    public final void print() {
        System.out.println("This is a shape.");
    }
}

public class Circle extends Shape {
    private double radius;
    public Circle(double r) {
        radius = r;
    }
    public double area() {
        return Math.PI * radius * radius;
    }
}

public class TestShape {
    public static void main(String[] args) {
        Circle circle = new Circle(5);
        circle.print();
        System.out.println("The area of the circle is " + circle.area());
    }
}

在上面的代码中,Shape类中定义了抽象方法area()和final方法print(),Circle类继承Shape类并实现area()方法,main方法中创建了一个Circle对象并调用其print()和area()方法。由于print()方法被定义为final方法,它不能被覆盖,即不能在Circle类中重写该方法。