📅  最后修改于: 2020-03-22 15:12:17             🧑  作者: Mango
先决条件:在Java中重写,继承
final是Java中用于限制某些功能的关键字。我们可以使用final关键字声明变量、方法和类。
将final与继承一起使用
在继承期间,我们必须声明带有final关键字的方法,在所有派生类中,我们都需要对它们执行相同的实现。注意,在继承的初始阶段不必声明最终方法(始终为基类)。我们可以在任何我们想要的子类中声明最终方法,如果任何其他类扩展了该子类,则它必须遵循与该子类相同的方法实现。
// Java展示final和继承一起使用
// 基类
abstract class Shape
{
private double width;
private double height;
// 构造函数
public Shape(double width, double height)
{
this.width = width;
this.height = height;
}
// getWidth被声明为final,任何子类不能重写此方法
public final double getWidth()
{
return width;
}
// getHeight被声明为final,任何子类不能重写此方法
public final double getHeight()
{
return height;
}
// getArea()被声明为final,任何子类不能重写此方法
abstract double getArea();
}
// 派生类1
class Rectangle extends Shape
{
// 构造器
public Rectangle(double width, double height)
{
// 调用构造函数
super(width, height);
}
// getArea被重写,被声明为final,任何子类不能重写此方法
// Rectangle cann't override it
@Override
final double getArea()
{
return this.getHeight() * this.getWidth();
}
}
// 派生类2
class Square extends Shape
{
// 构造器
public Square(double side)
{
// 调用构造器
super(side, side);
}
// getArea被重写,被声明为final,任何子类不能重写此方法
@Override
final double getArea()
{
return this.getHeight() * this.getWidth();
}
}
// 测试代码
public class Test
{
public static void main(String[] args)
{
// Rectangle对象
Shape s1 = new Rectangle(10, 20);
// Square对象
Shape s2 = new Square(10);
// s1的宽和高
System.out.println("s1宽 : "+ s1.getWidth());
System.out.println("s1高 : "+ s1.getHeight());
// s2的宽和高
System.out.println("s2宽 : "+ s2.getWidth());
System.out.println("s2高 : "+ s2.getHeight());
// s1的面积
System.out.println("s1面积 : "+ s1.getArea());
// s2的面积
System.out.println("s2面积 : "+ s2.getArea());
}
}
输出:
s1宽 : 10.0
s1高 : 20.0
s2宽 : 10.0
s2高 : 10.0
s1面积 : 200.0
s2面积 : 100.0
使用final防止继承
当一个类声明为final时,则不能将其子类化,即,任何其他类都不能对其进行扩展。例如,当创建一个不可变的类(如预定义的String类)时,这特别有用。以下片段说明了带有类的final关键字:
final class A
{
// 声明方法和fields
}
// 下面的声明不合法.
class B extends A
{
// ERROR! Can't subclass A
}
注意 :
使用final防止重写
当一个方法声明为final的话,就无法通过subclasses.The重写对象类做到这一点,它的一些方法是final的。以下片段通过方法说明了final关键字:
class A
{
final void m1()
{
System.out.println("这是一个final方法.");
}
}
class B extends A
{
void m1()
{
// 报错,不能重写.
System.out.println("非法!");
}
}
通常,Java在运行时动态地解决对方法的调用。这称为后期绑定或动态绑定。但是,由于无法重写final方法,因此可以在编译时解决对某个方法的调用。这称为早期绑定或静态绑定。