如何在Java中实例化抽象类?
抽象类是在Java中用“abstract”关键字声明的类。抽象类是面向对象编程 (OOP) 四大原则之一“继承”的概念。“继承”指的是Java类的特性,其中一个称为“子类”的类可以继承父类(通常称为“超类”)的所有属性。
在Java中,抽象类指的是其他子类可以从中继承的基础超类。它可以包含抽象方法和非抽象方法。
算法
步骤1 - 识别类中具有默认实现或无实现的方法。
步骤2 - 删除这些方法的实现。
步骤3 - 将abstract关键字添加到类声明中。
步骤4 - 将abstract关键字添加到步骤2中修改的方法声明中。
步骤5 - 如果类有任何需要初始化的实例变量,请添加一个构造函数来初始化它们。
步骤6 - 更新抽象类的任何子类以实现抽象方法或自身成为抽象类。
语法
让我们看看在Java中实例化抽象类的语法 -
// Abstract Class
abstract class Shape {
public abstract void draw();
}
方法
由于抽象类是不完整的类,因此不能直接使用“new”关键字对其进行实例化。
具体子类 - 为了正确实例化一个原本模棱两可或不完整的抽象类,可以选择使用一个具体子类。通过从这个父抽象类无缝扩展并实现其每个方法要求,用户可以成功创建和实现这个新实例化的子类,而不会出现操作中的错误或不一致。
Lambda表达式 - 要从抽象类创建对象,您还有另一个选择 - 使用lambda表达式为其所有抽象提供实现。然后根据这些签名将此lambda创建分配给兼容的功能接口变量。
实例化抽象类
让我们来看一个示例代码片段,以了解抽象类的用法。第一个场景提供了一个带有非抽象类的代码。
示例
class Shape {
public void printName() {
System.out.println("I'm a shape");
}
public float area() {
return 0;
}
public void printDetails() {
this.printName();
System.out.println("... and my area is " + this.area());
}
}
class Circle extends Shape {
private float radius;
public Circle(float radius) {
this.radius = radius;
}
public void printName() {
System.out.println("I'm a circle");
}
public float area() {
return (float) (Math.PI * Math.pow(radius, 2));
}
}
class Rectangle extends Shape {
private float length;
private float width;
public Rectangle(float length, float width) {
this.length = length;
this.width = width;
}
public void printName() {
System.out.println("I'm a rectangle");
}
public float area() {
return length * width;
}
}
public class Main {
public static void main(String[] args) {
Shape[] shapes = { new Circle(3.5f), new Rectangle(4.0f, 5.0f) };
for (Shape shape : shapes) {
shape.printDetails();
}
}
}
输出
I'm a circle ... and my area is 38.48451 I'm a rectangle ... and my area is 20.0
Circle和Rectangle类都继承了“Shape”超类中的printName()、area()和printDetails()方法。但是,这两个类都没有重写area()方法来提供自己的实现。
通过在Circle对象上调用printDetails()方法,输出将为“我是一个圆……我的面积是38.48451”。同样,在Rectangle对象上调用printDetails()方法将输出“我是一个矩形……我的面积是20.0”。这确保了输出反映了正确的形状及其相应的面积,基于每个类中提供的具体实现。
示例1:具体子类
// With abstract class
abstract class Shape {
public abstract void printName();
public abstract float area();
public void printDetails() {
this.printName();
System.out.println("... and my area is " + this.area());
}
}
// Concrete class
class Circle extends Shape {
private float radius;
public Circle(float radius) {
this.radius = radius;
}
public void printName() {
System.out.print("I'm a circle");
}
public float area() {
return (float) (Math.PI * Math.pow(radius, 2));
}
}
// Concrete class
class Rectangle extends Shape {
private float length;
private float width;
public Rectangle(float length, float width) {
this.length = length;
this.width = width;
}
public void printName() {
System.out.print("I'm a rectangle");
}
public float area() {
return length * width;
}
}
// Main class
public class Main {
public static void main(String[] args) {
Shape[] shapes = { new Circle(10), new Rectangle(5, 10) };
for (Shape shape : shapes) {
shape.printDetails();
}
}
}
输出
I'm a circle... and my area is 314.15927 I'm a rectangle... and my area is 50.0
在上面更新的代码中,Circle和Rectangle类已经实现了在“Shape”抽象类中定义的抽象方法printName()和area()。Shape类中的printDetails()方法能够使用这些方法来打印形状名称及其各自的面积。
通过将Shape设为抽象类并定义抽象方法,我们确保扩展Shape类的任何类都必须为printName()和area()方法提供自己的实现。
示例2:Lambda表达式
interface Nameable {
String getName();
}
abstract class Shape {
private Nameable nameable;
public Shape(Nameable nameable) {
this.nameable = nameable;
}
public abstract float area();
public void printDetails() {
System.out.println("I'm a " + nameable.getName() + " ... and my area is " + this.area());
}
}
class Circle extends Shape {
private float radius;
public Circle(float radius) {
super(() -> "circle");
this.radius = radius;
}
@Override
public float area() {
return (float) (Math.PI * Math.pow(radius, 2));
}
}
class Rectangle extends Shape {
private float width;
private float height;
public Rectangle(float width, float height) {
super(() -> "rectangle");
this.width = width;
this.height = height;
}
@Override
public float area() {
return width * height;
}
}
public class Main {
public static void main(String[] args) {
Shape[] shapes = { new Circle(10), new Rectangle(5, 10) };
for (Shape shape : shapes) {
shape.printDetails();
}
}
}
输出
I'm a circle ... and my area is 314.15927 I'm a rectangle ... and my area is 50.0
在我们最近对这段代码的更新中,我们通过将Shape指定为抽象类并将其getName()函数内部化,引入了一种改进的方法。进一步的改进包括集成一个printName方法,该方法成功地利用getName()的数据来显示每个形状的名称。关于Circle和Rectangle子类 - 它们现在使用lambda表达式重写其对应的getNames,以便准确识别预期的形式。
结论
总之,抽象类只能通过其基子类实例化,而不能直接实例化。这是继承的一个概念。
其背后的主要原因是抽象类不是其方法和对象的完整实现,并且子类使用它们来继承。
数据结构
网络
关系数据库管理系统 (RDBMS)
操作系统
Java
iOS
HTML
CSS
Android
Python
C语言编程
C++
C#
MongoDB
MySQL
Javascript
PHP