W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
1.封裝(Encapsulation); 2.繼承(Inheritance); 3.多態(tài)(Polymorphism)
什么是封裝?
封裝就是隱藏實(shí)現(xiàn)細(xì)節(jié),僅對(duì)外提供訪問接口
封裝的類型有:屬性封裝、方法封裝、類封裝、組件封裝、模塊化封裝、系統(tǒng)級(jí)封裝....
封裝的兩個(gè)含義:
1.把對(duì)象的狀態(tài)和行為看成一個(gè)統(tǒng)一的整體,將二者存放在一個(gè)獨(dú)立的模塊中(類)
2."信息隱藏",把不需要讓外界知道的信息隱藏起來,盡可能隱藏對(duì)象功能實(shí)現(xiàn)細(xì)節(jié),字段
封裝機(jī)制在程序中的體現(xiàn):
把描述對(duì)象的狀態(tài)用字段表示,描述對(duì)象的行為用方法表示,把字段和方法定義在一個(gè)類中,并保證外界不能任意更改其內(nèi)部的字段值,也不允許任意調(diào)動(dòng)其內(nèi)部的功能方法
封裝在程序中的一種體現(xiàn):通常將類中的成員變量私有化(private),通過對(duì)外提供方法(set方法,get方法),可對(duì)該變量(xxx)進(jìn)行訪問
屬性的封裝
當(dāng)某些屬性或方法被修飾為私有的,那么這些屬性或方法就不能被類的外面直接訪問
(1).把屬性定義為私有的(只能在本類中訪問)
(2).為屬性提供getter取值方法、setter設(shè)置方法
封裝的優(yōu)點(diǎn)
● 1. 良好的封裝能夠減少耦合
● 2. 類內(nèi)部的結(jié)構(gòu)可以自由修改
● 3. 可以對(duì)成員變量進(jìn)行更精確的控制
● 4.模塊化、信息隱藏、實(shí)現(xiàn)細(xì)節(jié)、代碼重用、插件化易于調(diào)試、具有安全性
實(shí)現(xiàn)JAVA封裝步驟
1.修改屬性的可見性來限制對(duì)屬性的訪問(一般為private修飾符)
/**
*定義一個(gè)Person類
*隱藏信息
**/
public class Person {
private String name; //定義私有的屬性
private int age; //定義私有屬性
}
這段代碼中,將 name 和 age 屬性設(shè)置為私有的,只能本類才能訪問,其他類都訪問不了,如此就對(duì)信息進(jìn)行了隱藏
2.對(duì)每個(gè)值屬性提供對(duì)外的公共方法訪問,也就是創(chuàng)建一對(duì)賦取值方法,用于對(duì)私有屬性的訪問:
/**
*定義一個(gè)Person類,隱藏信息并提供訪問
**/
public class Person{
private String name; //定義私有的屬性
private int age; //定義私有的屬性
//取得getAge方法
public int getAge(){
return age;
}
//取得getName方法
public String getName(){
return name;
}
//設(shè)置setAge方法
public void setAge(int age){
this.age = age;
}
//設(shè)置setName方法
public void setName(String name){
this.name = name;
}
}
什么是繼承(extends)?
子類自動(dòng)共享父類數(shù)據(jù)和方法的機(jī)制,這是類之間的關(guān)系就是叫做繼承
繼承概念:被繼承的類稱為父類(超類),繼承父類的類稱為子類(派生類)
繼承是指一個(gè)對(duì)象直接使用另一個(gè)對(duì)象的屬性和方法,通過繼承可以實(shí)現(xiàn)代碼重用
super關(guān)鍵字:可以通過super關(guān)鍵字來實(shí)現(xiàn)對(duì)父類成員的訪問,用來引用當(dāng)前對(duì)象的父類
使用super調(diào)用父類中的屬性,調(diào)用父類的方法,調(diào)用父類中的構(gòu)造方法
super 表示父類對(duì)象的默認(rèn)引用
super如果子類要調(diào)用父類被覆蓋的實(shí)例方法,可用super作為調(diào)用者調(diào)用父類被覆蓋的實(shí)例方法
使用super調(diào)用父類方法,使用super調(diào)用父類的構(gòu)造方法
this 與super 區(qū)別
| NO. | 區(qū)別 | this | super |
| :-------- | --------:| :------: | :------: |
| 1. | 使用 | 調(diào)用本類中的字段或方法 | 從子類調(diào)用父類中的字段或方法 |
| 2. | 構(gòu)造 | 可以調(diào)用本類構(gòu)造方法,且有一個(gè)構(gòu)造方法要作為出口 | 從子類調(diào)用父類的構(gòu)造方法,不管子類如何安排最終一定會(huì)去調(diào)用,默認(rèn)調(diào)用的是父類中的無參構(gòu)造方法 |
| 3. | 要求 | 調(diào)用自身構(gòu)造方法時(shí)放在構(gòu)造方法首行 | 調(diào)用父類構(gòu)造方法時(shí)放在子類構(gòu)造方法首行 |
| 4. | 特殊 | 表示當(dāng)前對(duì)象 | 表示父類對(duì)象 |
方法的覆寫:方法覆寫又稱為方法覆蓋
產(chǎn)生原因:當(dāng)父類中某個(gè)方法不適合于子類時(shí),子類出現(xiàn)父類一模一樣的方法
調(diào)用被覆蓋的父類方法:使用super.方法名(實(shí)參);
方法覆寫時(shí)應(yīng)遵循的原則(一同,兩小,一大):
(一同):方法簽名必須相同;
(兩小):子類方法的返回值類型比父類方法的返回值類型更小或相等
子類方法聲明拋出的異常應(yīng)比父類方法申明拋出的異常更小或相等
(一大):子類方法的訪問權(quán)限應(yīng)比父類方法更大或相等
(Overload 重載) 與 (Override 覆寫) 區(qū)別
| NO. | 區(qū)別 | (Overload)重載 | (Override)覆寫 |
| :-------- | --------:| :------: | :------: |
| 1. | 判斷規(guī)則 | 兩同一不同 | 一同兩小一大 |
| 2. | 權(quán)限 | 沒有權(quán)限要求 | 被覆寫的方法不能擁有比父類更嚴(yán)格的權(quán)限 |
| 3. | 范圍 | 發(fā)生在一個(gè)類中 | 發(fā)生在繼承關(guān)系中 |
| 4. | 術(shù)語 | Overload | Override |
| 5. | 多態(tài) | 編譯時(shí)多態(tài) | 運(yùn)行時(shí)多態(tài) |
子類對(duì)象實(shí)例化過程
在繼承操作中,對(duì)于子類對(duì)象的實(shí)例化:
子類對(duì)象在實(shí)例化之前必須首先調(diào)用父類中的構(gòu)造方法之后再調(diào)用自身的構(gòu)造方法
在子類進(jìn)行實(shí)例化操作時(shí),首先會(huì)讓其父類進(jìn)行實(shí)例化操作(調(diào)用父類的構(gòu)造方法),之后子類再自己進(jìn)行實(shí)例化操作
子類訪問父類;
子類不能直接訪問父類的私有成員,但是子類可以調(diào)用父類中的非私有方法來間接訪問父類的私有成員
在 JAVA中,類的繼承是單一繼承,也就是說,一個(gè)子類只能擁有一個(gè)父類,所以 extends 只能繼承一個(gè)類
類的繼承格式:在 JAVA中通過 extends 關(guān)鍵字可以申明一個(gè)類是從另外一個(gè)類繼承而來的
/**
*定義一個(gè)類
**/
class 父類 {
}
/**
*定義一個(gè)類繼承父類
**/
class 子類 extends 父類 {
}
為什么需要繼承? :接下來筆者通過代碼實(shí)例來說明這個(gè)需求
開發(fā)汽車類,其中汽車分別為奧迪A6以及奔馳R350,要求如下:
● 奧迪A6:屬性(id,車名,顏色,速度),方法(汽車基本信息,汽車動(dòng)力信息)
● 奔馳R350:屬性(id,車名,顏色,速度),方法(汽車基本信息,汽車動(dòng)力信息)
奧迪A6 汽車類
public class AudiA6 {
private int id; //定義私有汽車id號(hào)屬性
private String carname; //定義私有車名屬性
private String colors; //定義私有顏色屬性
private double speed; //定義私有速度屬性
//定義帶參構(gòu)方法
public AudiA6(int id,String carname,String colors,double speed){
this.id = id;
this.carname = carname;
this.colors = colors;
this.speed = speed;
}
//取得getId方法
public int getId(){
return id;
}
//取得getCarname方法
public String getCarname(){
return carname;
}
//取得getColors方法
public String getColors(){
return colors;
}
//取得getSpeed方法
public String getSpeed(){
return speed;
}
//設(shè)置setId方法
public void setId(int Id){
this.id = id;
}
//設(shè)置setCarname方法
public void setCarname(String carname){
this.carname = carname;
}
//設(shè)置setColors方法
public void setColors(String colors){
this.colors = colors;
}
//設(shè)置setSpeed方法
public void setSpeed(double speed){
this.speed = speed;
}
//定義汽車基本信息方法
public void carinformation(){
System.out.println("汽車基本信息:" +id+carname+colors); //輸出汽車id,車名,顏色
}
//定義汽車動(dòng)力信息方法
public void information(){
System.out.println("汽車動(dòng)力信息"+ speed); //輸出速度
}
}
奔馳R350 汽車類
public class MercedesBenzR350 {
private int id; //定義私有汽車id號(hào)屬性
private String carname; //定義私有車名屬性
private String colors; //定義私有顏色屬性
private double speed; //定義私有速度屬性
//定義帶參構(gòu)方法
public MercedesBenzR350 (int id,String carname,String colors,double speed){
this.id = id;
this.carname = carname;
this.colors = colors;
this.speed = speed;
}
//取得getId方法
public int getId(){
return id;
}
//取得getCarname方法
public String getCarname(){
return carname;
}
//取得getColors方法
public String getColors(){
return colors;
}
//取得getSpeed方法
public String getSpeed(){
return speed;
}
//設(shè)置setId方法
public void setId(int Id){
this.id = id;
}
//設(shè)置setCarname方法
public void setCarname(String carname){
this.carname = carname;
}
//設(shè)置setColors方法
public void setColors(String colors){
this.colors = colors;
}
//設(shè)置setSpeed方法
public void setSpeed(double speed){
this.speed = speed;
}
//定義汽車基本信息方法
public void carinformation(){
System.out.println("汽車基本信息:" +id+carname+colors); //輸出汽車id,車名,顏色
}
//定義汽車動(dòng)力信息方法
public void information(){
System.out.println("汽車動(dòng)力信息"+ speed); //輸出速度
}
}
<font color="red"&從這兩段代碼我們可以看出來,存在太多重復(fù)代碼,導(dǎo)致后果就是代碼量大且非常多,而且維護(hù)性不高(維護(hù)性主要是后期需要修改的時(shí)候,就需要修改很多的代碼,容易出錯(cuò))</font&
所以要從根本上解決這兩段代碼的問題,我們就需要繼承,將兩段代碼中相同的部分提取出來組成 一個(gè)父類
公共的汽車父類:
public class Cars {
private int id; //定義私有汽車id號(hào)屬性
private String carname; //定義私有車名屬性
private String colors; //定義私有顏色屬性
private double speed; //定義私有速度屬性
//定義帶參構(gòu)方法
public Cars (int id,String carname,String colors,double speed){
this.id = id;
this.carname = carname;
this.colors = colors;
this.speed = speed;
}
//取得getId方法
public int getId(){
return id;
}
//取得getCarname方法
public String getCarname(){
return carname;
}
//取得getColors方法
public String getColors(){
return colors;
}
//取得getSpeed方法
public String getSpeed(){
return speed;
}
//設(shè)置setId方法
public void setId(int Id){
this.id = id;
}
//設(shè)置setCarname方法
public void setCarname(String carname){
this.carname = carname;
}
//設(shè)置setColors方法
public void setColors(String colors){
this.colors = colors;
}
//設(shè)置setSpeed方法
public void setSpeed(double speed){
this.speed = speed;
}
//定義汽車基本信息方法
public void carinformation(){
System.out.println("汽車基本信息:" +id+carname+colors); //輸出汽車id,車名,顏色
}
//定義汽車動(dòng)力信息方法
public void information(){
System.out.println("汽車動(dòng)力信息"+ speed); //輸出速度
}
}
<font color="red"&這個(gè)Cars類就可以作為一個(gè)父類,然后奧迪A6汽車類和奔馳R350汽車類繼承Cars公共汽車類之后,就具有父類當(dāng)中的屬性和方法,子類就不會(huì)存在重復(fù)的代碼,維護(hù)性也提高,代碼也更加簡潔,提高代碼的復(fù)用性(復(fù)用性主要是可以多次使用,不用再多次寫同樣的代碼)</font&
繼承之后的代碼:
奧迪A6汽車類 繼承Cars公共類:
public class AudiA6 extends Cars {
//帶參構(gòu)造方法
public AudiA6(int id,String carname,String colors,double speed) {
super(id, carname, colors, speed);
}
//定義汽車基本信息方法
public void carinformation(){
super.carinformation(); //super調(diào)用父類的方法
}
//定義汽車動(dòng)力信息方法
public void information(){
super.carinformation(); //super調(diào)用父類的方法
}
}
奔馳R350汽車類 繼承Cars公共類:
public class MercedesBenzR350 extends Cars {
public MercedesBenzR350(int id,String carname,String colors,double speed) {
super(id, carname, colors, speed);
}
//定義汽車基本信息方法
public void carinformation(){
super.carinformation(); //super調(diào)用父類的方法
}
//定義汽車動(dòng)力信息方法
public void information(){
super.carinformation(); //super調(diào)用父類的方法
}
}
繼承的特性
● 子類擁有父類非private的屬性,方法
● 子類可以擁有自己的屬性和方法,即子類可以對(duì)父類進(jìn)行擴(kuò)展
● 子類可以用自己的方式實(shí)現(xiàn)父類的方法
● Java的繼承是單繼承,但是可以多重繼承,單繼承就是一個(gè)子類只能繼承一個(gè)父類
多重繼承就是,例如A類繼承B類,B類繼承C類,所以按照關(guān)系就是C類是B類的父類,B類是A類的父類
這是java繼承區(qū)別于C++繼承的一個(gè)特性
● 提高了類之間的耦合性(繼承的缺點(diǎn),耦合度高就會(huì)造成代碼之間的聯(lián)系)
什么是多態(tài)?: 多態(tài)性指同一個(gè)實(shí)體同時(shí)具有多種形式
多態(tài)是同一個(gè)行為具有多個(gè)不同表現(xiàn)形式或形態(tài)的能力,多態(tài)性是對(duì)象多種表現(xiàn)形式的體現(xiàn)
譯時(shí)的類型由聲明該變量時(shí)使用的類型決定
運(yùn)行時(shí)的類型由實(shí)際賦給變量的對(duì)象決定,如果編譯時(shí)類型和運(yùn)行時(shí)類型不同,就出現(xiàn)多態(tài)性
生活中多態(tài)的例子:
比如我們說"寵物"這個(gè)對(duì)象,它就有很多不同的表達(dá)或?qū)崿F(xiàn),比如有小貓、小狗、等等
那么我到寵物店說"請(qǐng)給我一只寵物",服務(wù)員給我小貓、小狗或者蜥蜴都可以,我們就說"寵物"這個(gè)對(duì)象就具備多態(tài)性
多態(tài)的實(shí)現(xiàn)方式:
1.方法的重載(同一個(gè)類里面,返回值相同,方法名相同,參數(shù)的個(gè)數(shù)不同),重寫(發(fā)生在子類與父類關(guān)系中)
2.對(duì)象的多態(tài)性:是從繼承關(guān)系中的多個(gè)類而來,引用變量類型轉(zhuǎn)換
向上轉(zhuǎn)型:將子類實(shí)例化轉(zhuǎn)為父類實(shí)例格式:
向上轉(zhuǎn)型(子類→父類):(自動(dòng)完成) 父類名稱 父類對(duì)象 = 子類實(shí)例 ;
向下轉(zhuǎn)型(父類→子類):(強(qiáng)制完成) 子類名稱 子類對(duì)象 = (子類名稱)父類實(shí)例 ;
3.接口
● 生活中的接口最具代表性的就是插座,例如一個(gè)三接頭的插頭都能接在三孔插座中,因?yàn)檫@個(gè)是每個(gè)國家都有各自規(guī)定的接口規(guī)則,有可能到國外就不行,那是因?yàn)閲庾约憾x的接口類型
● JAVA中的接口類似于生活中的接口,就是一些方法特征的集合,但沒有方法的實(shí)現(xiàn)
4.抽象類和抽象方法
多態(tài)的作用:把不同的子類對(duì)象都當(dāng)作父類來看,可以屏蔽不同子類對(duì)象之間的差異,寫出通用的代碼,做出通用的編程,以適應(yīng)需求的不斷變化,只修改方法的實(shí)現(xiàn),不必修改方法的聲明,繼承是多態(tài)產(chǎn)生的前提條件
多態(tài)的分類:編譯時(shí)多態(tài):方法重載,運(yùn)行時(shí)多態(tài):方法覆寫
多態(tài)的優(yōu)點(diǎn)
● 1. 消除類型之間的耦合關(guān)系
● 2. 可替換性
● 3. 可擴(kuò)充性
● 4. 接口性
● 5. 靈活性
● 6. 簡化性
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: