如何在Java中实例化一个抽象类?

如何在Java中实例化一个抽象类?

抽象类是在 Java 中通过“Abstract”关键字声明的类。抽象类是面向对象编程 (OOP) 的四个原则之一的概念,称为“继承”。继承是指 Java 类的一种特性,其中一个称为“子类”的类可以继承该类的所有属性。父类通常称为“超类”。

在Java中,抽象类是指其他子类可以继承的基超类。它可以包含抽象方法和非抽象方法。

算法

  • 第 1 步 - 识别类中具有默认实现或无实现的方法。

  • 步骤 2 - 删除这些方法的实现。

  • 第 3 步 - 将抽象关键字添加到类声明中。

  • 步骤 4 - 将抽象关键字添加到步骤 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 表达式重写相应的 getName,以便准确识别预期的形式。

结论

总而言之,抽象类只能通过其基子类实例化,而不能直接实例化。这是一个继承的概念。

这背后的主要原因是抽象类并不是其方法和对象的完整实现,而是被子类用来继承它们。

以上就是如何在Java中实例化一个抽象类?的详细内容,更多请关注其它相关文章!