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