標籤:
一、概述
物件導向除了封裝、繼承和多態三大特徵之外,還有其他的特性,例如abstract抽象、interface介面等,抽象類別主要作為多個類的模板,而介面則定義了多類應該遵守的規範,final關鍵字讓java實現不可變類,讓系統更加安全。
二、本文
1、構造器和初始化塊
1.1 構造器
構造器是一種特殊方法,這個特殊方法用於建立執行個體時執行初始化,是建立對象的重要途徑,如果程式員沒有為JAVA類提供任何構造器,則系統會為這個類提供一個無參數的構造器,這個構造器的執行體為空白,不做任何事情。無論如何,JAVA類至少包含一個構造器。
具體代碼如下:
public class A{ private String name; private int age; A(String name){ //this關鍵字代表本來引用 this.name = name; } //自訂構造器,含兩個參數,名稱必須和類名相同 A(String name,int age){ this(name); this.age = age; } }class Test{ public static void main(String[] args){ //根據構造器生產對象 A a = new A("zhang",5); A a1 = new A(); System.out.print("name"+a.name+"age"+a.age); System.out.print("name"+a1.name+"age"+a1.age); }}
通過上面的程式我們可以看出,構造器是建立JAVA對象的重要途徑,通過new 關鍵字建立構造器,一旦程式員提供了自訂的構造器,則系統不再提供預設的構造器,如果不自訂無參數構造器,將不能通過無參構造器建立對象,一個類可以有多個建構函式,名字必須相同,但參數不能相同。程式中this(name)用this關鍵字調用該類的無參建構函式,而且使用this必須放在第一條語句。
1.2 初始化快
Java通過構造器對單個對象進行初始化,與之功能類似的是初始化塊,它也可以對對象進行初始塊。具體文法格式如下:
[修飾符]{ //初始化塊的可執行代碼......}
修飾符只能是static,使用static修飾的稱為靜態初始化塊,初始化塊裡的程式碼封裝括定義局部變數,調用其他對象的方法,以及使用分支、迴圈語句等。如果不寫修飾符的稱為普通初始化塊。下面是一段簡單的代碼:
class Test{ //普通初始化塊 { //初始化塊執行語句 } //靜態初始化塊 static { //靜態初始化塊執行語句 } Test() { //無參數建構函式執行語句 }}
上面程式如果執行Test test = new Test();時,那麼它的執行順序是先執行靜態初始化塊,然後普通初始化塊,最後才是Test()。
注意:初始化塊隨著類的載入而執行,只執行一次,對所有對象進行初始化。
2、抽象類別
在某些情況下,某個父類只是知道其子類應該包含怎樣的方法,但是無法準確的知道這些子類如何?這些方法,例如定義一個People類,這個類提供了一個eat()方法,但不同的People子類的eat()方法是不一樣的,即People無法準確的描述eat()方法。那麼如何既能讓People()包含eat()方法,又無須提供其他方法實現呢?這時使用抽象方法即可滿足該要求。抽象方法和類的具體特徵如下:
1、抽象類別和方法必須使用abstract修飾,抽象方法不能有方法體。
2、抽象類別不能被執行個體化。
3、抽象類別和普通類沒多大區別,可以包含成員變數、方法、構造器、初始化塊和枚舉類6種成分。抽象類別的構造器不能建立執行個體,主要用於被其子類調用。
4、含有抽象方法的類,必須被定義成抽象類別。
5、抽象類別只能被子類繼承,子類想要建立執行個體對象,必須複寫所有抽象方法,如果只是複寫了一部分,子類也必須是抽象類別。
下面是一段簡單的代碼:
//定義抽象類別abstract class People{ //普通成員變數 private String name; //建構函式 public People(String name){ this.name = name; } //普通方法 public void enjoy(){ System.out.println("people"); } //聲明抽象方法 public abstract void eat(); }//student繼承People,並複寫了eat()抽象方法//這樣student才能被建立執行個體,不複寫的話student也必須是abstractclass student extends People{ public void eat(){ System.out.println("student"); }}
注意:抽象類別也可以不包含抽象方法,只能被繼承。它是從多個具有相同特徵的類中抽取出來的,具備相同的特徵,以這個抽象類別作為其子類模板,從而避免了子類設計的隨意性。
3、介面
介面是一種特殊的抽象類別,不能包含普通方法,介面中的所有方法都是抽象方法。具體文法如下:
[修飾符] interface 介面名 [extends 父介面名列表]{[public] [static] [final] 常量;[public] [abstract] 方法;
修飾符:可選,用於指定介面的存取權限,可選值為public。如果省略則使用預設的存取權限。
介面名:必選參數,用於指定介面的名稱,介面名必須是合法的Java標識符。一般情況下,要求首字母大寫。
extends 父介面名列表:選擇性參數,用於指定要定義的介面繼承於哪個父介面。當使用extends關鍵字時,父介面名為必選參數。
方法:介面中的方法只有定義而沒有被實現。
那麼介面在什麼時候定義呢?比如,有兩個及上的的類擁有相同的方法,但是實現功能不一樣,就可以定義一個介面,將這個方法提煉出來,在需要使用該方法的類中去實現,就免除了多個類定義系統方法的麻煩。下面是一個簡單的例子代碼:
//定義介面Ainterface A { void a(); } //定義介面Binterface B { void b(); } /介面C繼承了A又實現了Binterface C extends A implements B { void c();} //介面D實現了C,必須要複寫了C中所有的抽象方法,即a()和b(),不然class D implements C{ public void a() { System.out.println("a"); } public void b() { System.out.println("b"); public void c() { System.out.println("c"); } } } //public class cam2 { static public void main(String args[]) { //產生的D的執行個體,並調用方法 D a=new D(); a.a(); a.b(); a.c(); } }
上面代碼有介面A和B,C繼承了A實現了B,其實也可以同時實現AB,AB之間只需要逗號隔開就可以,後面D有實現了C,那麼D就必須複寫ABC中的所有抽象方法,不然就不能被執行個體化。
注意:介面是對外暴露的規則,介面可以繼承介面,可以被多實現,通常情況下把事物的共性功能去被子類繼承,擴充功能放在介面裡被實現。
4、單例和final關鍵字
4.1 單例
單例是解決類在記憶體中只存在一個對象的最有效方法,下面是一段代碼:
//懶漢式public class Singleton { //私人化聲明變數 private static Singleton uniqueInstance = null; //私人化建構函式,保證不被其他類執行個體化 private Singleton() { // Exists only to defeat instantiation. } //對外提供public static方法提供自身執行個體 public static Singleton getInstance() { if (uniqueInstance == null) { uniqueInstance = new Singleton(); } return uniqueInstance; } // Other methods... }
從代碼可以看出,想要保證對象的唯一性,那麼步驟是:
1.為避免其他程式建立該對象執行個體,必須私人化建構函式
2.在本類中建立一個本類執行個體
3.為了方便其他程式訪問,可以對外提供訪問方式
上面介紹的懶漢式單例方法,是延時載入,還有一種是餓漢式,具體代碼如下:
//餓漢式單例類.在類初始化時,已經自行執行個體化 public class Singleton1 { //私人的預設構造子 private Singleton1() {} //已經自行執行個體化 private static final Singleton1 single = new Singleton1(); //對外提供自身執行個體 public static Singleton1 getInstance() { return single; } }
注意:開發中一般用餓漢式,懶漢式面試時用的多,因為懶漢式有缺點,容易造成多次建立執行個體,不能保證執行個體的唯一性。
4.2 final關鍵字
final可以修飾類、變數和方法,也可修飾局部變數和形參。那麼他的特徵是:
1.修飾變數時,說明該變數一旦被賦值就不可被改變,一般情況下格式是public static final int MAX,這個稱為全域常量,注意常量名大寫。
2.被final修飾的類不可被繼承,防止被子類繼承之後複寫裡面的方法。
3.被final修飾的方法不可被複寫。
三、總結
上面介紹了構造器和初始化塊,它們是用來給對象初始化用的,介面和抽象類別提高了函數的複用性,大大提高開發效率,單例是一種設計模式,java還有很多這樣的設計模式,為開發帶來了很大的方便。
黑馬程式員——Java基礎---物件導向(下)