Java final和abstract的区别
在使用Java时,理解final和abstract的概念对于编写高效且易于维护的代码至关重要。虽然最终和抽象在面向对象编程中都起着重要的作用,但它们的用途不同。在本文中,我们将探讨Java中final和abstract关键字的语法结构和使用方式,以及不同的实现方法。
语法
为了定义一个final类或方法,在类或方法声明前使用关键字”final”。例如,定义一个final类如下:
final class MyClass {
// Class implementation
}
为了对抽象类或策略进行描述,我们在类或方法声明之前使用关键字”abstract”。例如,一个抽象类可以被定义如下:
abstract class MyAbstractClass {
// Class implementation
}
语法解释
最后的”关键字用来表示一个类、方法或变量不会被修改或覆盖。最终的类不能被子类化,最后的方法不能在任何子类中被覆盖。此外,最后的变量在被赋值后不能再重新赋值。
另一方面,”抽象”关键字用来表示一个类或方法是不完整的,必须由另一个类来扩展或实现。抽象类不能直接实例化,它可能包含由它的子类来实现的抽象方法。
方法1:Final
在这种方法中,我们将重点介绍final关键字的用法。使用final的主要目的是在Java中创建不可变的实体。不可变的对象是那些一旦创建就无法改变状态的对象。
步骤
- 声明类或方法为final。
-
在类或方法中实现期望的功能。
-
防止其他类或子类进行进一步修改。
示例
final class ImmutableClass {
private final String name;
public ImmutableClass(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public class Main {
public static void main(String[] args) {
ImmutableClass immutableObject = new ImmutableClass("Hello");
System.out.println(immutableObject.getName());
}
}
输出
Hello
解释方法1中的代码
ImmutableClass被指定为既不可变也不可扩展,这是因为在声明时包含了”final”关键字。它包含一个名为”name”的私有实例变量,也被标记为final,以防止在构造函数中分配后进行修改。
ImmutableClass的构造函数接受一个名为name的String参数,并将其值赋给name变量。这确保name变量只能在对象创建时设置一次,之后不能修改。
在ImmutableClass内部存在一种公开的方法,通过一个命名合理的getName()方法来查找对象的名称。由于该名称元素被指定为私有,外部访问必须被禁止,因此需要实现这个可查找的工具。我们程序的入口点是Main类的main()函数,我们在其中用”Hello”作为命名参数实例化一个ImmutableClass的实例。
初始化后,我们将新实例存储在内存节省变量immutableObject下。我们通过指定System.out.println()的输出流等于immutableObject之前详细介绍的getName()方法的返回值来结束我们的main函数,这样我们的程序就会显示成功执行并在屏幕上显示”Hello”(我们最初指定的名称)。
方法2:抽象
在这种方法中,我们将专注于使用abstract关键字。抽象类用于提供一种公共接口和描述相关类的公共行为。
步骤
- 声明类为抽象类。
-
定义应由子类实现的抽象方法。
-
在抽象类中实现公共功能。
示例
abstract class Shape {
protected String color;
public Shape(String color) {
this.color = color;
}
abstract double getArea();
}
class Circle extends Shape {
private double radius;
public Circle(String color, double radius) {
super(color);
this.radius = radius;
}
@Override
double getArea() {
return Math.PI * radius * radius;
}
}
public class Main {
public static void main(String[] args) {
Circle circle = new Circle("Red", 2.5);
System.out.println("Color: " + circle.color);
System.out.println("Area: " + circle.getArea());
}
}
输出
Color: Red
Area: 19.634954084936208
Shape类被声明为一个抽象类,使用abstract关键字。抽象类不能被实例化,意味着不能直接创建Shape类的对象。Shape类有一个受保护的实例变量color,以及一个构造函数,该构造函数接受一个color参数,并将其值分配给color变量。
Shape类还声明了一个名为getArea()的抽象方法。从程序的角度来看,抽象方法在创建框架和结构化代码实现方面起着关键作用。具体而言,开发人员可以使用这个工具集创建方法和结构,而不必立即在运行时确定下来,而是留待后续的具体子类(即引入的类别之外的类)开发。
让我们特别来看一下getArea()在这里的关联-简要地说:根据形状分类和各种开发人员在其中使用的子类型因素来计算面积是有所不同的。因此,将这个变化因素放置在非立即或独立的开发中,允许任何具体的子类在不考虑整体结构崩溃或之前子级创建时的完整性维护问题的情况下实现定制化。对于我们在这里的基础工作也是相关的,可以看到Shape被扩展为Circle这样的子类,并通过进一步调整以与具有类似开发模板的其他结构集成。它添加了一个私有实例变量radius,并拥有一个构造函数,该构造函数接受颜色和半径参数。Circle的构造函数使用super关键字调用其超类(Shape)的构造函数来初始化color变量。然后,将radius参数分配给Circle类的radius变量。
Circle类覆盖了从Shape类继承的getArea()方法。在这种情况下,它使用公式计算圆的面积: π * 半径 * 半径。Math.PI常量表示pi的值(约为3.14159)。
这个编程序列的基础是Main类,在其中我们可以找到main方法-确立了程序的起点。在这个方法中,我们创建了一个Circle对象,初始半径为2.5,颜色为“Red”。这个新对象从其各自的构造函数中获取信息:首先调用Circle构造函数,然后调用Shape构造函数来重置其颜色值。最后,我们将“circle”指定为这个特定实例的变量名。
最后,通过circle.color访问circle对象的颜色变量,并将其打印到控制台。还调用了circle对象上的getArea()方法,并将返回值打印到控制台。
Java中final和abstract之间的区别
差异点 | 方法一:Final | 方法二:abstract |
---|---|---|
实例化 | 允许类的实例化 | 不能直接实例化 |
继承 | 不能被子类化 | 允许子类化 |
方法重写 | 方法不能被重写 | 抽象方法必须由子类实现 |
可修改性 | 防止类、方法或变量的修改 | 为子类提供修改和扩展的蓝图 |
使用方式 | 用于创建不可变实体或强制特定行为 | 用于定义相关类的共同接口和行为 |
结论
总之,虽然final和abstract在Java编程中具有不同的目的,但它们都是重要的工具。通过合理地使用它们,你可以编写更健壮、灵活和易于维护的代码,符合设计原则并满足特定要求。无论是创建不可变实体还是建立通用接口,final和abstract关键字都对开发高质量的Java应用程序有所贡献。