第一 封裝
一、概述
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、.函數:(覆蓋(重寫))
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、操作同一個大類型,對其中的小類型都可以操作