如何在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