Java基礎---> 面向對象與java特性(封裝、繼承、多態

第一 封裝

一、概述

1、定義:封裝是指隱藏對象的屬性和實現細節,僅對外提供公共訪問方式。

2、好處:

a.將變化隔離

b.便於使用

c.提高重用性

d.提高安全性

3、原則:

a.將不需要對外提供的內容隱藏起來

b.把屬性都隱藏,提供公共方法對其訪問

4、說明:

a.私有僅僅是封裝的一種表現形式,如包也是一種封裝形式

b.之所以對外提供訪問方式,就是因爲可以在訪問方式中加入邏輯判斷等語句,對訪問的數據進行操作,提高了代碼的健壯性。

第二 繼承

一、概述

       當兩個事物之間存在一定的所屬關係,就像學生和工人都是人,也都具有人的共同特性如姓名等,我們就把人封裝成一個類(這個類中存放共性的成員),然後在分別定義學生和工人這兩個類中讓他們分別繼承人這個類,在人與學生和人與工人之間就有了所屬關係這種就稱爲繼承,從而學生和工人就具有了人的特性。在java中一個繼承的類(爲子類)可以從被繼承的類(爲父類或者超類)中獲得一些屬性和方法,而不必再自己創建新方法(在不需要複寫的情況等)。

、特點:

1、提高代碼複用性,定義在父類中的成員(變量和方法),可以被子類重複使用;

2、讓類與類之間產生關係,這樣就會有多態的特性。使得應用起來更方便。

需要注意的是:

A.不可以只是爲了獲取其他類的功能,簡化代碼就一味的使用繼承;必須是類與類之間有所屬關係,纔可以用繼承,這種關係稱爲“is-a”。

B.java語言中,只支持單繼承,不支持多繼承。究其原因,是因爲多繼承容易帶來安全隱患:

a.當多個父類中定義了相同的功能,且功能內容不同時,子類對象並不確定要運行哪一個,這就造成了程序的混亂而導致異常出現。

b但是java保留了這種機制,並改良了多繼承爲多實現,而且接口就可以多繼承。

三、使用繼承體系中的功能

1、如果使用體系,要先對體系中父類的描述進行參閱,瞭解父類中的共性功能,即可以使用該體系了。這樣既可以減少查閱時間,也能更系統的瞭解體系結構,以及父類的功能。

2、具體調用父類中的功能的時候,需要創建子類對象,通過子類對象對父類方法調用,實現繼承。爲何要通過創建子類對象調用父類中的方法呢?原因如下:

        a.父類很可能不可以創建對象,如父類是一個抽象類或者接口,這就需要子類創建對象,調用方法。

        b.創建子類對象,可以使用更多的功能,如父類公有的,和子類中自定義的特有功能。

單一句話:查閱父類功能,創建子類對象使用功能。

四、子父類出現後,類成員的特點:類成員:變量、函數、構造函數

1、變量:

        子父類中出現非私有的同名成員變量是,子類訪問本類的同名時,要用this關鍵字(如果省略了this,仍是代表本類的變量);子類訪問父類同名變量時,用super關鍵字。

        補充:this和super兩者都存在與方法區中。

           this:本類對象引用,那個對象調用this所在的函數,this就代表那個對象。

           super:父類對象引用,用於子類初始化父類構造函數、調用父類成員等。

           this和super不能同時存在與構造函數中。

2、.函數:(覆蓋(重寫))

當子類同父類出現相同函數時,子類對象調用該函數時,會運行子類內容,如同覆蓋穀類函數一樣。實際上並沒有覆蓋父類的函數,如果還需要調用父類的這個方法,需要用super.方法名即可。
class Fu{
	Fu(){
	}
	void method(){
		System.out.println("Fu......");
	}
}

class Zi extends Fu{
	Zi(){
		//super();//隱式的super語句,調用父類中默認的無參構造函數
		//子類比有調用父類構造函數的地方,因爲子類必須知道父類成員變量的初始化,才能操作其變量
		//this和super不能同時存在,因爲他們都必須在構造函數的第一行,這是因爲他們都是查看構造函數的初始化的
		//構造函數不存在重寫
	}
	void method(){//重寫,當對象調用時,執行重寫後的函數
		System.out.println("Zi......");
	}
}

重寫的應用:

      1、當子類繼承了父類就沿襲了父類的功能,在子類中雖然具備此功能,但是功能主體卻不一樣,此時就需要重寫父類中的方法,以達到功能擴展的效果。

注意:

       1、子類權限必須大於或等於父類權限才能覆蓋

       2、靜態只能覆蓋靜態,這個一般不用,因爲被覆蓋後在多態中是靜態加載的,容易出問題。

3、構造函數

       子類繼承了父類也就具備了父類的屬性(變量)和功能(方法),所以在加載子類對象之前,子類需要先知道父類構造函數是怎麼對其成員變量進行初始化的。也就是因爲這樣,所以子類的構造函數的第一行都有一條隱式的super();以調用父類的默認的構造函數。如果父類自定義了構造函數,且沒有無參的構造函數,這時就需要我們通過super(參數)區自己制定調用父類的構造函數。而且子類必有一個構造函數會訪問父類的構造函數。

補充:

因爲繼承是對封裝性的一個極大挑戰,所以就引入了final關鍵字

       final:根據程序上下文環境,Java關鍵字final有“這是無法改變的”或者“終態的”含義,它可以修飾非抽象類、非抽象類成員方法和變量。你可能出於兩種理解而需要阻止改變。 
final類不能被繼承,沒有子類,final類中的方法默認是final的。 
final方法不能被子類的方法覆蓋,但可以被繼承。 
final成員變量表示常量,只能被賦值一次,賦值後值不再改變。 
final不能用於修飾構造方法。 

 第三 多態

一、概述:

多態:可以理解爲事物之間存在多種形態。

如:人有男人和女人。其中男人可以稱爲男人,也可以稱爲人

二、多態的體現:

1、父類的引用指向了自己的子類對象

2、父類的引用頁可以接受自己的子類對象

如:Person p = new Student();這句話就是在棧內存中產生一個p,然後在堆內存中產生一個Student的對象,然後把Student的對象地址值賦給p,也就是p就指向了Student的對象。

三、多態的前提:

1、必須是類與類之間存在着關係,要麼繼承、要麼覆蓋。

2、通常還有一個前提:存在覆蓋

四、多態的利弊:

1、好處:大大的提高了程序的擴展性

2、弊端:雖然提高了擴展性,但是隻能使用父類的父類的引用訪問父類中的成員,不可預先使用子類。這是因爲子類在父類之後加載。

Animal a = new Cat();//類型提升,可以調用共性方法
Cat c = (Cat)a;//強轉回所屬類型,只有這樣才能調用子類中特有的方法

注意:

1、不能將父類對象轉換成子類類型

2、只有父類引用指向自己子類對象才能轉換,可類型提升,也可以強轉回子類

3、多態至始至終都是子類在做着變化

abstract class Animal
{
	abstract void eat();

}

class Cat extends Animal
{
	public void eat()
	{
		System.out.println("喫魚");
	}
	public void catchMouse()
	{
		System.out.println("抓老鼠");
	}
}


class Dog extends Animal
{
	public void eat()
	{
		System.out.println("喫骨頭");
	}
	public void kanJia()
	{
		System.out.println("看家");
	}
}


class Pig extends Animal
{
	public void eat()
	{
		System.out.println("飼料");
	}
	public void gongDi()
	{
		System.out.println("拱地");
	}
}

//-----------------------------------------


class DuoTaiDemo 
{
	public static void main(String[] args) 
	{
		//Cat c = new Cat();
		//c.eat();

		//Dog d = new Dog();
		//d.eat();
		//Cat c = new Cat();
		/*
		Cat c1 = new Cat();
		function(c1);

		function(new Dog());
		function(new Pig());
		*/

		//Animal c = new Cat();
		//c.eat();

		
		function(new Cat());
		function(new Dog());
		function(new Pig());
		

		
	}
	public static void function(Animal a)//Animal a = new Cat();
	{
		a.eat();
		//a.catchMouse();
	}
	/*
	public static void function(Cat c)//
	{
		c.eat();
	}
	public static void function(Dog d)
	{
		d.eat();
	}

	public static void function(Pig p)
	{
		p.eat();
	}
	*/

}

五、多態的特點:

1、成員函數的特點:

    編譯時期:參閱引用型變量所屬的類中是否有調用的方法,如果有編譯通過,沒有則編譯失敗。

    運行時期:參閱對象所屬的類中是否有調用的方法

總結:成員函數在多態調用是,編譯時看左邊,運行看右邊。子類局部有變量就訪問局部的,沒有就訪問子類全局的,子類沒有就訪問父類的

2、在多態中成員變量和靜態的特點:

    無論編譯和運行都參考左邊,即是引用型變量所屬的類型。也就是說父類中有就先找父類的。

    非靜態有重寫方法,靜態一般不被重寫

    因爲當調用靜態方法是,只要建立子類對象,父類與子類的靜態方法都會隨之加入方法區內存中,這就不需要對象直接可以用類名調用,只要引用還存在,就看引用變量的類型。

六、多態的應用:

1、定義好工具類,就是共同行爲封裝在一個類中

2、對類型進行抽取-->多態的產生

3、操作同一個大類型,對其中的小類型都可以操作


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章