Java之抽象類與抽象方法

Java之抽象類與抽象方法

抽象概念

本篇關鍵詞是抽象,那麼何爲抽象?百度百科告訴咱們,抽象就是歸納具體事務共同的方面、本質屬性等,而將個別的方面、屬性等捨棄的思惟過程。在Java裏,也就是把各個具體的類中共有的方法提取出來,放到基類之中,而基類並不須要瞭解子類中該方法具體是怎麼實現的,這個基類就是所謂的抽象類,這些不須要知道具體實現方式的方法就是抽象方法ide

抽象類體現模板模式的設計,抽象類做爲多個子類的通用模板,子類在抽象類的基礎上進行擴展、改造,但子類整體上會大體保留抽象類的行爲方式。工具

抽象類與方法

讓咱們結合代碼,好好地分析一波:學習

package com.my.pac18;

/**
 * @auther Summerday
 */
/*抽象是頗有用的重構工具,可以讓共有的方法沿着繼承層次向上移動。*/
public abstract class Shape {
    //抽象類中的初始化塊
    {
        System.out.println("Shape.instance initializer");
    }
    //抽象類中的實例變量
    private String color;
    //抽象類中能夠有靜態方法及屬性。
    public static String name="形狀";
    public static void output(){
        System.out.println("父類的static方法");
    }
    //計算周長,可是並不知道具體細節的抽象方法
    public abstract double calPerimeter();
    //返回形狀的抽象方法

    //[修飾符] abstract 返回類型 方法名();
    public abstract String getType();
    //抽象類中的構造器,用於被繼承
    public Shape() {
    }

    public Shape(String color) {
        System.out.println("Shape.Shape");
        this.color = color;
    }
    //抽象類中的普通實例方法
    public String getColor() {
        return color;
    }
}

class Circle extends Shape {
    private double radius;

    public Circle(String color, double radius) {
        super(color);
        this.radius = radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }

    @Override
    public double calPerimeter() {
        return 2 * Math.PI * radius;
    }

    @Override
    public String getType() {
        return getColor() + "圓形";
    }

    //若是從一個抽象類繼承,並建立該新類的對象,就必須給基類的全部抽象方法提供定義。
    public static void main(String[] args) {
        Shape.output();
        //Shape是抽象類,不能建立Shape類的對象
        //可是可讓Shape類的引用變量指向其子類的對象
        Shape[] shapes = new Shape[]{new Circle("紅色", 5), new Rectangle("綠色", 6, 6)};
        for (Shape p : shapes) {
            
            System.out.println(p.getType() + "的周長爲" + p.calPerimeter());
        }

    }
}

class Rectangle extends Shape {
    
    private double length;
    private double width;

    public Rectangle() {
        System.out.println("父類的構造器不是爲了建立對象,而是供給子類繼承的");
    }

    public Rectangle(String color, double length, double width) {
        super(color);
        this.length = length;
        this.width = width;
    }

    public boolean isSquare() {
        return length == width;
    }

    public double calPerimeter() {
        return (length + width) * 2;
    }

    public String getType() {
        if (isSquare()) return getColor() + "正方形";
        return getColor() + "長方形";
    }
}

//測試結果
父類的static方法
Shape.instance initializer
Shape.Shape
Shape.instance initializer
Shape.Shape
紅色圓形的周長爲31.41592653589793
綠色正方形的周長爲24.0

順着上面的例子,咱們簡單地分析一下,抽象類抽象方法究竟是啥?又須要注意些啥?測試

  • 首先定義了一個抽象類:Shape類。能夠看到,抽象類由abstract關鍵字修飾。
//[修飾符] abstract class 類名
public abstract class Shape
  • 而後再Shape類裏定義了兩個抽象方法(方法能夠被重寫,屬性不能夠,抽象是針對方法而言的):getType()calPerimeter()能夠看出抽象方法聲明時並無定義方法體,由於基類中並不須要知道具體的實現方式是怎樣,只要知道有這個方法就能夠了。你建立一個圓形實例,具體如何算圓形的周長,在圓形類給出抽象方法的定義便可。
//[修飾符] abstract 返回類型 方法名();
 public abstract double calPerimeter();
 public abstract String getType();

注意事項

  • 若是子類從抽象父類繼承而來,那麼子類就必須重寫父類的抽象方法,給出方法的具體實現形式。你的爸爸說你會算周長,你總得告訴你們周長怎麼算吧。可是,若是子類中也重寫父類的方法也聲明爲抽象的話,這時父類方法在子類中的實現也無效了。就比如,你說你也不知道怎麼算周長,隔壁小王纔是真的會。
@Override
public double calPerimeter() {
    return 2 * Math.PI * radius;
}
@Override
public String getType() {
    return getColor() + "圓形";
}
  • 抽象類不能實例化,不能用new來調用抽象類構造器建立抽象類的實例。能夠想象,既然是抽象的,建立它的實例就沒多大意義,建立具體實現的子類的實例才能解決問題。
  • 抽象類能夠用做一種數據類型,可讓抽象類的引用變量指向它的子類對象,很好理解,不這樣的話,抽象帶來的好處體如今哪呢。經過抽象類的引用變量調用抽象類中的方法,就可以根據動態綁定,在運行時根據引用對象的實際類型執行抽象方法的具體表現形式。
  • 抽象類中是可以有具體實現的成員方法(實例方法和類方法),以及明確的成員屬性(實例屬性和類屬性)。
//抽象類中的實例方法,子類繼承使用。
public String getColor() {
        return color;
    }
//抽象類中能夠有靜態方法和屬性,類名.方法(屬性)調用。
public static String name="形狀";
public static void output(){
    System.out.println("父類的static方法");
}
  • 抽象類中還能夠有構造器,可是僅僅是爲了供給子類繼承使用,由於上面講過,抽象類沒法建立實例對象!!!(重點回顧:子類沒法繼承父類構造器,只是單純調用父類構造器的初始化代碼,繼承和調用是不同的!!!
//子類
public Shape() {
    }

public Shape(String color) {
    System.out.println("Shape.Shape");
    this.color = color;
}
  • 抽象類中還有代碼塊和內部類,關於內部類以後將會學習,暫時就不舉例了。
//抽象類中的初始化塊
{
    System.out.println("Shape.instance initializer");
}
  • 一個類中若是有抽象方法,那麼這個類也必定是抽象的。畢竟你的方法定義尚且都不徹底,建立你的實例又有啥用呢。可是一個抽象類中能夠沒有抽象方法,只是單純不讓人建立它的實例對象。this

  • 子類是抽象,父類也能夠是具體的。如上,Object類是全部類的超類,它是具體的,咱們定義的Shape類是能夠抽象的。設計

  • 抽象是實現多態的一種機制,那麼不具有多態性的,就不能稱之爲多態。諸如private、static、final修飾的方法或構造器屬於靜態綁定,不具有多態性,不能做爲抽象的修飾。code

本文是根據資料以及我的測試以後所得,如有錯誤或者理解不當之處,還望評論區指出,謝謝。對象

相關文章
相關標籤/搜索