1. 程式人生 > 其它 >JAVA學習 理解多型,抽象類以及介面

JAVA學習 理解多型,抽象類以及介面

理解多型
多型的的概念:

程式碼示例: 列印多種形狀
class Shape {
    public void draw() {
    // 啥都不用幹
     }
}
class Cycle extends Shape {
@Override
public void draw() {
    System.out.println("○");
   }
}
class Rect extends Shape {
@Override
public void draw() {
    System.out.println("□");
    }
}
class
Flower extends Shape { @Override public void draw() { System.out.println("♣"); } } /我是分割線// // Test.java public class Test { public static void main(String[] args) { Shape shape1 = new Flower(); Shape shape2 = new Cycle(); Shape shape3 = new Rect(); drawMap(shape1); drawMap
(shape2); drawMap(shape3); } // 列印單個圖形 public static void drawShape(Shape shape) { shape.draw(); } }

在這個程式碼中, 分割線上方的程式碼是 類的實現者 編寫的, 分割線下方的程式碼是 類的呼叫者 編寫的.

當類的呼叫者在編寫 drawMap 這個方法的時候, 引數型別為 Shape (父類), 此時在該方法內部並不知道, 也不關注當 前的shape 引用指向的是哪個型別(哪個子類)的例項. 此時 shape 這個引用呼叫 draw 方法可能會有多種不同的表現 (和 shape 對應的例項相關), 這種行為就稱為 多型。

多型發生的基本條件:

1.發生向上轉型;
2.發生執行時繫結;

使用多型的好處是什麼?

  1. 類呼叫者對類的使用成本進一步降低. 封裝是讓類的呼叫者不需要知道類的實現細節. 多型能讓類的呼叫者連這個類的型別是什麼都不必知道,
    只需要知道這個物件具有某個方法即可. 因此, 多型可以理解成是封裝的更進一步, 讓類呼叫者對類的使用成本進一步降低.
  2. 能夠降低程式碼的"圈複雜度", 避免使用大量的 if - else
  3. 可擴充套件能力更強.
    如果要新增一種新的形狀, 使用多型的方式程式碼改動成本也比較低

例如我們現在需要列印的不是一個形狀了, 而是多個形狀. 如果不基於多型, 實現程式碼如下:

public static void drawShapes() {
    Rect rect = new Rect();
    Cycle cycle = new Cycle();
    Flower flower = new Flower();
    String[] shapes = {"cycle", "rect", "cycle", "rect", "flower"};
    for (String shape : shapes) {
        if (shape.equals("cycle")) {
            cycle.draw();
        } else if (shape.equals("rect")) {
            rect.draw();
            } else if (shape.equals("flower")) {
                 flower.draw();
            }
        }
   }

如果使用使用多型, 則不必寫這麼多的 if - else 分支語句, 程式碼更簡單

public static void drawShapes() {
// 我們建立了一個 Shape 物件的陣列.
    Shape[] shapes = {new Cycle(), new Rect(), new Cycle(),
    new Rect(), new Flower()};
    for (Shape shape : shapes) {
        shape.draw();
    }
}
class Triangle extends Shape {
@Override
public void draw() {
    System.out.println("△");
    }
}

對於類的呼叫者來說(drawShapes方法), 只要建立一個新類的例項就可以了, 改動成本很低.
而對於不用多型的情況, 就要把 drawShapes 中的 if - else 進行一定的修改, 改動成本更高。
抽象類:包含抽象方法的類 抽象類

  • 1、抽象類不能進行例項化 ; * 2、在抽象類當中,可以擁有和普通類一樣的資料成員和方法 * public int age;
  • public static int count; * public void func() {}
  • 3、抽象類是可以被繼承的,可以發生向上轉型。 *
    4、當一個普通類繼承了一個抽象類,那麼注意,當前這個普通類,一定要重寫抽象類當中的抽象方法。 *
  • 5、當普通類A繼承了抽象類,且不想實現抽象類當中的抽象方法的時候
    那麼這個普通類可以被修改為抽象類A,此時就不需要進行實現了,當然你也可以實現。 *
    如果一個普通類B,繼承了這個抽象類A,此時就要實現這個抽象方法。
  • 6、抽象方法不能是private修飾的,因為抽象方法就是用來被重寫的
  • 7、抽象類的出現 其實最大的意義就是為了被繼承。

介面:使用關鍵字 interface修飾

  • 1、介面當中的方法 ,不能有具體實現。 * 介面當中的方法,預設是:public abstract
  • 2、介面當中的成員變數,預設是 public static final
  • 3、JDK1.8引入的新特性。default修飾的方法,預設方法,可以有具體的實現
    4、介面不可以進行例項化;
  • 5、類和介面之間的關係是,implements
  • 6、一個類可以實現多個介面class Test implements A,B,C{
  • 7、一個類可以繼承類,同時實現多個介面 * class Test extends TestAbstract implements A,B,C{
  • 8、介面可以擴充套件多個介面:interface D extends A,B,C { * 所以 介面的出現就是為了解決java多繼承的問題