目錄
一、前言
二、封裝
1.什么是封裝???
2.封裝的特點(diǎn)
3.封裝的使用
三、繼承
1.什么是繼承?
2.繼承的特點(diǎn)
3.繼承的優(yōu)點(diǎn)
4.繼承的使用?
4.1 繼承的格式
?4.2 繼承的演示
4.3 成員變量
4.4 成員方法
4.5 構(gòu)造方法
五、多態(tài)
1.什么是多態(tài)?
2.多態(tài)的特點(diǎn)
3.多態(tài)的使用?
4.引用類型轉(zhuǎn)型
?5.為什么要做轉(zhuǎn)型?
?六、總結(jié)
一、前言
?????????今天總結(jié)一下關(guān)于Java的三大特性,封裝,繼承,多態(tài)。其實(shí)關(guān)于三大特性對(duì)于從事編程人員來(lái)說(shuō)都是基本的了,畢竟只要接觸Java這些都是先要認(rèn)識(shí)的,接下來(lái)就系統(tǒng)總結(jié)一下。
二、封裝
1.什么是封裝???
????????封裝(Encapsulation)是面向?qū)ο蠓椒ǖ闹匾瓌t,就是把對(duì)象的屬性和操作(或服務(wù))結(jié)合為一個(gè)獨(dú)立的整體,并盡可能隱藏對(duì)象的內(nèi)部實(shí)現(xiàn)細(xì)節(jié)。
- 將類的某些信息隱藏在類的內(nèi)部,不允許外部程序進(jìn)行直接的訪問(wèn)調(diào)用。
- 通過(guò)該類提供的方法來(lái)實(shí)現(xiàn)對(duì)隱藏信息的操作和訪問(wèn)。
- 隱藏對(duì)象的信息。
- 留出訪問(wèn)的對(duì)外接口。
? 舉個(gè)比較通俗的例子,比如我們的USB接口。如果我們需要外設(shè)且只需要將設(shè)備接入U(xiǎn)SB接口中,而內(nèi)部是如何工作的,對(duì)于使用者來(lái)說(shuō)并不重要。而USB接口就是對(duì)外提供的訪問(wèn)接口。
2.封裝的特點(diǎn)
- 對(duì)成員變量實(shí)行更準(zhǔn)確的控制。
- 封裝可以隱藏內(nèi)部程序?qū)崿F(xiàn)的細(xì)節(jié)。
- 良好的封裝能夠減少代碼之間的耦合度。
- 外部成員無(wú)法修改已封裝好的程序代碼。
- 方便數(shù)據(jù)檢查,有利于保護(hù)對(duì)象信息的完整性,同時(shí)也提高程序的安全性。
- 便于修改,體高代碼的可維護(hù)性。
3.封裝的使用
????????使用 private 關(guān)鍵字來(lái)修飾成員變量。對(duì)需要訪問(wèn)的成員變量,提供對(duì)應(yīng)的一對(duì) getXxx 方法 、 setXxx 方法。private是一個(gè)權(quán)限修飾符,代表最小權(quán)限, 可以修飾成員變量和成員方法, 被private修飾后的成員變量和成員方法,只在本類中才能訪問(wèn)。代碼示例:
public class Student {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
分析:對(duì)于上面的一個(gè)實(shí)體對(duì)象,我想大家都已經(jīng)很熟悉了。將對(duì)象中的成員變量進(jìn)行私有化,外部程序是無(wú)法訪問(wèn)的。但是我們對(duì)外提供了訪問(wèn)的方式,就是set和get方法。而對(duì)于這樣一個(gè)實(shí)體對(duì)象,外部程序只有賦值和獲取值的權(quán)限,是無(wú)法對(duì)內(nèi)部進(jìn)行修改,因此我們還可以在內(nèi)部進(jìn)行一些邏輯上的判斷等,來(lái)完成我們業(yè)務(wù)上的需要。
三、繼承
1.什么是繼承?
?????????繼承就是子類繼承父類的特征和行為,使得子類對(duì)象(實(shí)例)具有父類的實(shí)例域和方法,或子類從父類繼承方法,使得子類具有父類相同的行為。當(dāng)然,如果在父類中擁有私有屬性(private修飾),則子類是不能被繼承的。
2.繼承的特點(diǎn)
2.1 只支持單繼承,一個(gè)子類只允許有一個(gè)父類
2.2 子類可以擁有父類的屬性和方法
2.3 子類可以擁有自己的屬性和方法
2.4 子類可以重寫父類的方法
2.5 可以聲明父類,創(chuàng)建子類(又稱作為父類裝載子類)
??????例如:Person p=new Teacher();
? ? ? ? ? ??????(1) 聲明什么樣的類型,就只能調(diào)用什么類型的屬性和方法
? ? ? ? ? ??????(2) 創(chuàng)建什么樣的類型,就真正運(yùn)行的什么類型的方法
? ? ? ? ? ? ? ? ?提示: (1)和(2)稱為向上轉(zhuǎn)型, 例如:Person p=new Teacher();那么p只能調(diào)用Person類中的方法和屬性,但實(shí)際上運(yùn)行的是Teacher中所重寫的方法,無(wú)法調(diào)用Teacher中的私有的方法
? ? ? ? ? ????? (3) 創(chuàng)建什么樣的類型,就可以強(qiáng)轉(zhuǎn)為什么類型
? ? ? ? ? ? ? ? ?提示:例如: Person p=new Teacher();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Teacher t=(Teacher) p;
? ? ? ? ? ? ? ? ?這種叫做向下轉(zhuǎn)型,此時(shí)t調(diào)用的是創(chuàng)建的Teacher類型的相應(yīng)屬性和方法。
3.繼承的優(yōu)點(diǎn)
- 提高代碼發(fā)復(fù)用性
- 父類的屬性方法可以用于子類
- 可以輕松定義子類
- 使設(shè)計(jì)應(yīng)用程序變得簡(jiǎn)單
4.繼承的使用?
4.1 繼承的格式
class 父類 {
...
}
class 子類 extends 父類 {
...
}
?4.2 繼承的演示
/
* *
定義員工類Employee,做為父類
*/
class Employee {
String name; // 定義name屬性
// 定義員工的工作方法
public void work() {
System.out.println("盡心盡力地工作");
}
}
/
* *
定義講師類Teacher 繼承 員工類Employee
*/
class Teacher extends Employee {
// 定義一個(gè)打印name的方法
public void printName() {
System.out.println("name=" + name);
}
}
/
* *
定義測(cè)試類
*/
public class ExtendDemo01 {
public static void main(String[] args) {
// 創(chuàng)建一個(gè)講師類對(duì)象
Teacher t = new Teacher();
// 為該員工類的name屬性進(jìn)行賦值
t.name = "小明";
// 調(diào)用該員工的printName()方法
t.printName(); // name = 小明
// 調(diào)用Teacher類繼承來(lái)的work()方法
t.work(); // 盡心盡力地工作
}
}
4.3 成員變量
? ? ? ? 當(dāng)成員變量不重名時(shí),對(duì)代碼的訪問(wèn)是沒(méi)有影響的,但是當(dāng)成員的變量重名時(shí),這個(gè)時(shí)候訪問(wèn)就會(huì)出現(xiàn)問(wèn)題,例如:
class Fu {
// Fu中的成員變量。
int num = 5;
}
class Zi extends Fu {
// Zi中的成員變量
int num = 6;
public void show() {
// 訪問(wèn)父類中的num
System.out.println("Fu num=" + num);
// 訪問(wèn)子類中的num
System.out.println("Zi num=" + num);
}
}
class ExtendsDemo03 {
public static void main(String[] args) {
// 創(chuàng)建子類對(duì)象
Zi z = new Zi();
// 調(diào)用子類中的show方法
z.show();
}
}
演示結(jié)果:
Fu num = 6
Zi num = 6
????????子父類中出現(xiàn)同名的成員變量時(shí),在子類中訪問(wèn)父類中的非私有成員變量時(shí),需要使用super關(guān)鍵字來(lái)修飾父類成員變量,類似于this。例如:
class Zi extends Fu {
// Zi中的成員變量
int num = 6;
public void show() {
//訪問(wèn)父類中的num
System.out.println("Fu num=" + super.num);
//訪問(wèn)子類中的num
System.out.println("Zi num=" + this.num);
}
}
演示結(jié)果:
Fu num = 5
Zi num = 6
4.4 成員方法
? ? ? ? 當(dāng)成員方法出現(xiàn)重名時(shí),我們則需要用到方法重寫(Override)。
????????方法重寫 :子類中出現(xiàn)與父類一模一樣的方法時(shí)(返回值類型,方法名和參數(shù)列表都相同),會(huì)出現(xiàn)覆蓋效果,也稱為重寫或者復(fù)寫。聲明不變,重新實(shí)現(xiàn)。
class Phone {
public void sendMessage(){
System.out.println("發(fā)短信");
}
public void call(){
System.out.println("打電話");
}
public void showNum(){
System.out.println("來(lái)電顯示號(hào)碼");
}
}
//智能手機(jī)類
class NewPhone extends Phone {
//重寫父類的來(lái)電顯示號(hào)碼功能,并增加自己的顯示姓名和圖片功能
public void showNum(){
//調(diào)用父類已經(jīng)存在的功能使用super
super.showNum();
//增加自己特有顯示姓名和圖片功能
System.out.println("顯示來(lái)電姓名");
System.out.println("顯示頭像");
}
}
public class ExtendsDemo06 {
public static void main(String[] args) {
// 創(chuàng)建子類對(duì)象
NewPhone np = new NewPhone();
// 調(diào)用父類繼承而來(lái)的方法
np.call();
// 調(diào)用子類重寫的方法
np.showNum();
}
}
注意:這里在重寫時(shí),用到了super.父類成員方法,表示調(diào)用父類成員的方法。
4.5 構(gòu)造方法
????????首先我們要回憶兩個(gè)事情,構(gòu)造方法的定義格式和作用。
????????1. 構(gòu)造方法的名字是與類名一致的。所以子類是無(wú)法繼承父類構(gòu)造方法的。
????????2. 構(gòu)造方法的作用是初始化成員變量的。所以子類的初始化過(guò)程中,必須先執(zhí)行父類的初始化動(dòng)作。子類的構(gòu)造方法中默認(rèn)有一個(gè) super() ,表示調(diào)用父類的構(gòu)造方法,父類成員變量初始化后,才可以給子類使用。
class Fu {
private int n;
Fu(){
System.out.println("Fu()");
}
}
class Zi extends Fu {
Zi(){
// super(),調(diào)用父類構(gòu)造方法
super();
System.out.println("Zi()");
}
}
public class ExtendsDemo07{
public static void main (String args[]){
Zi zi = new Zi();
}
}
輸出結(jié)果:
Fu()
Zi()
五、多態(tài)
1.什么是多態(tài)?
????????多態(tài)是同一個(gè)行為具有多個(gè)不同表現(xiàn)形式或形態(tài)的能力。
2.多態(tài)的特點(diǎn)
- 消除類型之間的耦合關(guān)系,實(shí)現(xiàn)低耦合
- 靈活性
- 可擴(kuò)充性
- 可替換性
3.多態(tài)的使用?
多態(tài)體現(xiàn)的格式:
父類類型 變量名 = new 子類對(duì)象;
變量名.方法名();
當(dāng)使用多態(tài)方式調(diào)用方法時(shí),首先檢查父類中是否有該方法,如果沒(méi)有,則編譯錯(cuò)誤;如果有,執(zhí)行的是子類重寫后方法。
定義父類:
public abstract class Animal {
public abstract void eat();
}
定義子類:
class Cat extends Animal {
public void eat() {
System.out.println("吃魚");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨頭");
}
}
定義測(cè)試類:
public class Test {
public static void main(String[] args) {
// 多態(tài)形式,創(chuàng)建對(duì)象
Cat c = new Cat();
Dog d = new Dog();
// 調(diào)用showCatEat
showCatEat(c);
// 調(diào)用showDogEat
showDogEat(d);
/*
以上兩個(gè)方法, 均可以被showAnimalEat(Animal a)方法所替代
而執(zhí)行效果一致
*/
showAnimalEat(c);
showAnimalEat(d);
}
public static void showCatEat (Cat c){
c.eat();
}
public static void showDogEat (Dog d){
d.eat();
}
public static void showAnimalEat (Animal a){
a.eat();
}
}
????????由于多態(tài)特性的支持,showAnimalEat方法的Animal類型,是Cat和Dog的父類類型,父類類型接收子類對(duì)象,當(dāng)然可以把Cat對(duì)象和Dog對(duì)象,傳遞給方法。
????????當(dāng)eat方法執(zhí)行時(shí),多態(tài)規(guī)定,執(zhí)行的是子類重寫的方法,那么效果自然與showCatEat、showDogEat方法一致,所以showAnimalEat完全可以替代以上兩方法。
????????不僅僅是替代,在擴(kuò)展性方面,無(wú)論之后再多的子類出現(xiàn),我們都不需要編寫showXxxEat方法了,直接使用showAnimalEat都可以完成。
????????所以,多態(tài)的好處,體現(xiàn)在,可以使程序編寫的更簡(jiǎn)單,并有良好的擴(kuò)展。
4.引用類型轉(zhuǎn)型
多態(tài)的轉(zhuǎn)型分為向上轉(zhuǎn)型與向下轉(zhuǎn)型兩種:
向上轉(zhuǎn)型:多態(tài)本身是子類類型向父類類型向上轉(zhuǎn)換的過(guò)程,這個(gè)過(guò)程是默認(rèn)的。當(dāng)父類引用指向一個(gè)子類對(duì)象時(shí),便是向上轉(zhuǎn)型。
使用格式
父類類型 變量名 = new 子類類型();
如:Animal a = new Cat();
向下轉(zhuǎn)型:父類類型向子類類型向下轉(zhuǎn)換的過(guò)程,這個(gè)過(guò)程是強(qiáng)制的。
一個(gè)已經(jīng)向上轉(zhuǎn)型的子類對(duì)象,將父類引用轉(zhuǎn)為子類引用,可以使用強(qiáng)制類型轉(zhuǎn)換的格式,便是向下轉(zhuǎn)型。
使用格式:
子類類型 變量名 = (子類類型) 父類變量名;
如:Cat c =(Cat) a;
?5.為什么要做轉(zhuǎn)型?
當(dāng)使用多態(tài)方式調(diào)用方法時(shí),首先檢查父類中是否有該方法,如果沒(méi)有,則編譯錯(cuò)誤。也就是說(shuō),不能調(diào)用子類擁有,而父類沒(méi)有的方法。編譯都錯(cuò)誤,更別說(shuō)運(yùn)行了。這也是多態(tài)給我們帶來(lái)的一點(diǎn)"小麻煩"。所以,想要調(diào)用子類特有的方法,必須做向下轉(zhuǎn)型。
定義類:
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 watchHouse() {
System.out.println("看家");
}
}
定義測(cè)試類:
public class Test {
public static void main(String[] args) {
// 向上轉(zhuǎn)型
Animal a = new Cat();
a.eat(); // 調(diào)用的是 Cat 的 eat
// 向下轉(zhuǎn)型
Cat c = (Cat)a;
c.catchMouse(); // 調(diào)用的是 Cat 的 catchMouse
}
}
注意:此處在轉(zhuǎn)換時(shí),有時(shí)會(huì)出現(xiàn)轉(zhuǎn)換異常的情況,例如:
public class Test {
public static void main(String[] args) {
// 向上轉(zhuǎn)型
Animal a = new Cat();
a.eat(); // 調(diào)用的是 Cat 的 eat
// 向下轉(zhuǎn)型
Dog d = (Dog)a;
d.watchHouse(); // 調(diào)用的是 Dog 的 watchHouse 【運(yùn)行報(bào)錯(cuò)】
}
}
????????這是因?yàn)?,明明?chuàng)建了Cat類型對(duì)象,運(yùn)行時(shí),當(dāng)然不能轉(zhuǎn)換成Dog對(duì)象的。這兩個(gè)類型并沒(méi)有任何繼承關(guān)系,不符合類型轉(zhuǎn)換的定義。為了避免ClassCastException的發(fā)生,Java提供了 instanceof 關(guān)鍵字,給引用變量做類型的校驗(yàn),格式如下:
變量名 instanceof 數(shù)據(jù)類型
如果變量屬于該數(shù)據(jù)類型,返回true。
如果變量不屬于該數(shù)據(jù)類型,返回false。
所以在轉(zhuǎn)換前我們可以先做一個(gè)判斷文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-718408.html
public class Test {
public static void main(String[] args) {
// 向上轉(zhuǎn)型
Animal a = new Cat();
a.eat(); // 調(diào)用的是 Cat 的 eat
// 向下轉(zhuǎn)型
if (a instanceof Cat){
Cat c = (Cat)a;
c.catchMouse(); // 調(diào)用的是 Cat 的 catchMouse
} else if (a instanceof Dog){
Dog d = (Dog)a;
d.watchHouse(); // 調(diào)用的是 Dog 的 watchHouse
}
}
}
?六、總結(jié)
? ? ? ? 以上就是小編收集的關(guān)于java的封裝、繼承、多態(tài)的知識(shí)點(diǎn)了,有問(wèn)題的地方歡迎評(píng)論交流呀,期待和各位一起變強(qiáng)呀?。?!文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-718408.html
到了這里,關(guān)于Java系列——封裝、繼承、多態(tài)初了解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!