1. 程式人生 > >7、面向物件的思想和體現

7、面向物件的思想和體現

       java是一種面向物件的程式設計語言,在程式中使用物件來描述具體的事物,當多個事物具有共同的特點時,可以將事物的共同特點進行抽象,然後封裝成一個包含事物共同特點的集合,在java中叫做封裝成一個類,可以將面向物件的主要特點是(抽象)封裝、繼承和多型。

封裝

       所謂抽象,就是將一些具體的事物之間存在的共同之處抽取出來,然後形象化的描述,在java中抽象的過程就是將事物共同的靜態屬性和動態屬性封裝成類的過程,事物的靜態屬性可以抽象成變數,動態屬性則可以封裝成一個方法(函式),封裝是面向物件的核心思想,封裝指的的是將物件的屬性和動作進行封裝,對外隱藏本身的實現細節。例如:狗、貓,可以找他們之間的共同點,都有顏色這一屬性,則可以封裝一個顏色屬性到類中;再者他們都要吃飯,則可以封裝一個吃飯的方法到類中,不管是狗還是貓,我們只需要知道他們能吃飯就可以了,並不需要具體瞭解他們吃飯的具體步驟,這就是對外開放但是隱藏本身的實現細節。

 類、方法、變數

        定義類、變數和方法時都會用到許可權修飾符:public、protected、default、private,被public修飾的變數和方法可以隨便訪問;被protected、private修飾的變數和方法只能在當前類中使用。

        類中可以包含變數和方法,具體的實現程式碼必須要寫在具體的方法中,變數又分為區域性變數和成員變數,方法中宣告的變數就是區域性變數,類裡邊、方法外邊宣告的變數就是成員變數,變數的定義包含以下部分:修飾符、變數型別、變數名 ,程式碼如下:


public class Dog{
    //變數的宣告
    //private 私有修飾符
    //int 變數型別
    //color 變數名
    private int color;

}

方法的定義包含以下部分:修飾符、返回值型別(構造方法除外)、方法名、方法體。類中的方法根據功能劃分可分為兩類,一類時構造方法、另一類是普通的方法,構造方法用來構造當前類的物件,初始化物件的屬性,而普通的方法就是根據物件動態屬性抽象過來的方法。程式碼如下:

public class Animal {

	public String color;
	
	/**
	 * 構造方法,沒有返回值,方法名和類名相同,可用於初始化類中封裝的變數
	 */
	public Animal(String color) {
		//this.color中的color指的是當前類中的變數
		//第二個color是區域性變數color的值
		//this關鍵字可用於表示當前類
		this.color = color;
	}
	
	/**
	 * 普通方法,int是返回值型別,eat是方法名 
	 */
	public int eat() {
		//區域性變數
		int flag = 0;
		System.out.println("Animal在吃飯。。。");
		return flag;//返回值
	}
	
}

定義方法時可以呼叫其他的方法,方法可以被過載,一個類中不可以定義完全相同的兩個方法,但是可以定義兩個方法名相同但是引數列表不同的方法,這兩個方法的關係就是過載,程式碼如下:

public class Animal {

	/*
	 * 兩個方法的方法名相同引數列表不同則兩個方法過載,和返回值無關,方法可以過載多個
	 */
	
	public void eat() {
		
	}
	
	public int eat(int flag) {
		
		return flag;
	}
	
	public void eat(String flag) {
		
	}
}

每一個類就相當於一個模板,可以根據這個模板創造出具體的物件,在java中使用new關鍵字來建立物件,使用 “.” 來呼叫類中公開的方法和變數程式碼如下:

class Animal {

	public int flag;
	
	public void eat() {
		System.out.println("正在吃飯");
	}
	
}

public class Test {
	public static void main(String[] args) {
		
		Animal animal = new Animal();//建立物件
		
		animal.eat();//呼叫方法
		
	}
	
}

繼承、抽象類、介面

       當一個類被封裝後,一般不鼓勵二次封裝,一般當類的功能不足以支援當前需求時,我們會考慮對此類進行擴充套件,java中可以使用繼承來實現這一想法。例如這裡有類A,類中有一個計算四邊形周長的方法,但是現在想計算正方形的周長,雖然計算四邊形周長的方法可以用於計算正方形,但是想實現的簡單點,就可以再封裝一個類B,然後B繼承類A,在java中用關鍵字extends來表示繼承,B extends A,這就叫做類B繼承自類A,A是B的父類,B是類A的子類,然後可以在B中重新宣告一個方法用來計算正方形的周長。子類可以使用父類所有公開的屬性和方法,每一個類只能繼承一個父類(例如:在血緣關係上,一個兒子只有一個父親),所以java中是單繼承。再如上邊的計算四邊形的方法,如果在子類中宣告一個方法,此方法與父類中的方法完全相同,這就是方法的重寫。程式碼如下:

public class Animal {

	public int flag;
	
	public void eat() {//這裡已經聲明瞭eat方法
		System.out.println("正在吃飯");
	}
	
}

-----------------------------------------------------------------------------------

//Dog類繼承了Animal類,擁有了Animal類的公開的功能
public class Dog extends Animal{

	@Override//這個註解的意思是重寫方法
	public void eat() {//重寫父類方法
		System.out.println("Dog在吃飯。。。");
	}
}

         在寫程式碼的過程中,聲明瞭一個方法,但是不知如何實現,這時可以將方法體刪掉,然後使用修飾符abstract 來修飾這個方法,這個方法就叫做抽象方法,如果一個類中存在抽象方法,那麼這個類必須使用abstract修飾,以將此類標記成抽象類,如果一個類中的所有方法都是抽象的,那麼這個類就可以宣告成一個介面,使用interface 來宣告介面。抽象類和介面都不可以例項化(就是指不可以使用new關鍵字來建立物件)。抽象類可以被繼承,如果子類宣告的不是抽象類,那麼就必須重寫繼承的抽象父類中的所有抽象方法。介面可以被實現,使用implements 關鍵字進行介面的實現,實現介面的類如果不宣告成抽象類,就必須重寫實現介面中所有的方法,一個類不可以繼承多個類,但是可以實現多個介面,這樣就解決的java單繼承的尷尬。程式碼如下:

//宣告介面 interface
public interface Animal {

	//宣告一個方法
	public abstract void run();
	
}

//宣告介面 interface
interface Animal2 {

	//宣告一個方法
	public abstract void eat();
	
}

------------------------------------------------------------------------------

//實現Animal,Animal2介面,重寫介面中的方法,如果多個介面,則每一個介面中的方法都要實現
public class Dog implements Animal ,Animal2{

	@Override
	public void eat() {
		System.out.println("dog eat ...");
		
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		
	}
	
}

static、final

         static關鍵字意為靜態的意思,static可以修飾變數、方法、程式碼塊,只需要記住一點:被static修飾的屬性和方法是所有根據當前類建立的物件所共享的,一個物件做出修改,其他物件就會修改,在記憶體中只有一份。

         final關鍵字意為最終之意,final可用來修飾類、方法、變數,被修飾的類不可被繼承、被修飾的方法不能重寫、被修飾的變數不能重新賦值。秩序記住一點,只要被final修飾,什麼東西就都不能改了,保持最終的狀態。

多型

         最後說一下多型的理解,所謂多型就是多種狀態,統一類的不同物件所表現的不同的狀態,就是父類(介面)的引用指向子類(實現類)的物件,實現多型有以下幾中方式 :繼承類、實現介面。例如封裝一個動物類,類中有動物的顏色這一變數、動物吃飯方法,然後分別封裝狗類和貓類,然後狗類和貓類都繼承動物類,這時我宣告一個動物類的變數,然後建立物件的時候,將此變數指向一個狗的物件,以為狗屬於動物(狗類繼承自動物類),這時動物就表現出了多型性,建立誰的物件,這個動物就會表現出誰的狀態。程式碼實現如下:

public class Animal {

	public String color;
	
	public void eat() {
		System.out.println("Animal在吃飯。。。");
	}
	
}

-------------------------------------------------------------------------------------

public class Dog extends Animal{

	@Override
	public void eat() {
		System.out.println("Dog在吃飯。。。");
	}
}

class Cat extends Animal{

	@Override
	public void eat() {
		System.out.println("Cat在吃飯。。。");
	}
}

-------------------------------------------------------------------------------------

public class Test {
	public static void main(String[] args) {
		
		normal();//正常執行,不表現多型
		
		poly(); //表現多型
	}
	
	/**
	 * 正常呼叫
	 * @author chaizepeng
	 *
	 */
	public static void normal() {
		Animal animal = new Animal();
		animal.eat();
		
		Dog dog = new Dog();
		dog.eat();
		
		Cat cat = new Cat();
		cat.eat();
	}
	
	/**
	 * 表現出多型性
	 * @author chaizepeng
	 *
	 */
	public static void poly() {
		Animal animalDog = new Dog();
		animalDog.eat();
		
		Animal animalCat = new Cat();
		animalCat.eat();
	}
}