訪問(wèn)控制修飾符
信息隱藏是 OOP 最重要的功能之一,也是使用訪問(wèn)修飾符的原因钠糊。在編寫(xiě)程序時(shí)杉女,有些核心數(shù)據(jù)往往不希望被用戶(hù)調(diào)用,需要控制這些數(shù)據(jù)的訪問(wèn)倾剿。
對(duì)類(lèi)成員訪問(wèn)的限制是面向?qū)ο蟪绦蛟O(shè)計(jì)的一個(gè)基礎(chǔ)筷频,這有利于防止對(duì)象的誤用。只允許通過(guò)一系列定義完善的方法來(lái)訪問(wèn)私有數(shù)據(jù),就可以(通過(guò)執(zhí)行范圍檢查)防止數(shù)據(jù)賦予不正當(dāng)?shù)闹怠?br>
作用:
- 防止對(duì)封裝數(shù)據(jù)的未授權(quán)訪問(wèn)截驮。
- 有助于保證數(shù)據(jù)完整性。
- 當(dāng)類(lèi)的私有實(shí)現(xiàn)細(xì)節(jié)必須改變時(shí)际度,可以限制發(fā)生在整個(gè)應(yīng)用程序中的“連鎖反應(yīng)”葵袭。
訪問(wèn)范圍 | private | default(默認(rèn)) | protected | public |
---|---|---|---|---|
同一個(gè)類(lèi) | 可訪問(wèn) | 可訪問(wèn) | 可訪問(wèn) | 可訪問(wèn) |
同一包中的其他類(lèi) | 不可訪問(wèn) | 可訪問(wèn) | 可訪問(wèn) | 可訪問(wèn) |
不同包中的子類(lèi) | 不可訪問(wèn) | 不可訪問(wèn) | 可訪問(wèn) | 可訪問(wèn) |
不同包中的非子類(lèi) | 不可訪問(wèn) | 不可訪問(wèn) | 不可訪問(wèn) | 可訪問(wèn) |
public class Person {
private String name;
private int age;
public Person(){}
public Person(String name,int age){
this.name = name;
this.age = age;
}
public void display(){
System.out.println("姓名:"+this.name+",年齡:"+this.age);
}
public static void main(String[] args) {
Person p = new Person("wqc",20);
p.display();
}
}
一、封裝
隱藏內(nèi)部的實(shí)現(xiàn)細(xì)節(jié)乖菱,對(duì)外提供公共的訪問(wèn)方式坡锡。封裝可以被認(rèn)為是一個(gè)保護(hù)屏障,防止該類(lèi)的代碼和數(shù)據(jù)被外部類(lèi)定義的代碼隨機(jī)訪問(wèn)窒所。
作用:
- 良好的封裝能夠減少耦合鹉勒。
- 類(lèi)內(nèi)部的結(jié)構(gòu)可以自由修改。
- 可以對(duì)成員變量進(jìn)行更精確的控制吵取。
- 隱藏信息禽额,實(shí)現(xiàn)細(xì)節(jié)。
1.封裝實(shí)現(xiàn)
私有化屬性后皮官,對(duì)每個(gè)值屬性提供對(duì)外的公共方法訪問(wèn)脯倒,也就是創(chuàng)建一對(duì)賦取值方法,用于對(duì)私有屬性的訪問(wèn)捺氢。
public class Person{
private String name;
private int age;
?
public int getAge(){
return age;
}
?
public String getName(){
return name;
}
?
public void setAge(int age){
this.age = age;
}
?
public void setName(String name){
this.name = name;
}
}
public class Test {
public static void main(String[] args) {
Person p = new Person();
p.setName("小王");
p.setAge(20);
System.out.println("姓名:"+p.getName());
System.out.println("年齡:"+p.getAge());
}
}
其中使用的
this
關(guān)鍵字是為了區(qū)別局部變量和成員變量
二藻丢、繼承
繼承實(shí)現(xiàn)了類(lèi)層面的封裝,提取了一個(gè)或多個(gè)類(lèi)中的共性?xún)?nèi)容摄乒,定義在父類(lèi)悠反,子類(lèi)哦通過(guò)繼承父類(lèi)去訪問(wèn)父類(lèi)屬性和方法。
所以馍佑,繼承就是子類(lèi)繼承父類(lèi)的特征和行為斋否,使得子類(lèi)對(duì)象(實(shí)例)具有父類(lèi)的實(shí)例域和方法,或子類(lèi)從父類(lèi)繼承方法挤茄,使得子類(lèi)具有父類(lèi)相同的行為
1.實(shí)現(xiàn)
class Person {
private String name;
private int age;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name=name;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age=age;
}
}
class Student {
private String name;
private int age;
private String schoolName;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name=name;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age=age;
}
public String getSchoolName()
{
return schoolName;
}
public void setSchoolName(String schoolName)
{
this.schoolName=schoolName;
}
}
以上代碼可以看出如叼,兩個(gè)類(lèi)中有很多重復(fù)的內(nèi)容,不符合Java語(yǔ)言的開(kāi)發(fā)規(guī)范穷劈,這段代碼不僅從代碼上重復(fù)笼恰,而且從概念上講學(xué)生一定是人,只是學(xué)生類(lèi)描述的范圍小歇终,具備更多的屬性和方法社证,這個(gè)時(shí)候想要消除結(jié)構(gòu)定義上的重復(fù),就要用到繼承评凝。
class Person {
private String name;
private int age;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name=name;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age=age;
}
}
class Student extends Person{
private String stuNo;
public void setStuNo(String stuNo){
this.stuNo = stuNo;
}
public String getStuNo(){
return stuNo;
}
}
public class Test2{
public static void main(String[] args)
{
Student student=new Student();
student.setName("花花");
student.setAge(18);
System.out.println("姓名:"+student.getName()+" 年齡:"+student.getAge());
}
}
通過(guò)以上代碼可以發(fā)現(xiàn)追葡,當(dāng)發(fā)生了類(lèi)繼承關(guān)系之后,子類(lèi)可以直接繼承父類(lèi)的操作,可以實(shí)現(xiàn)代碼的重用宜肉,子類(lèi)最低也維持和父類(lèi)相同的功能匀钧。
格式:
class 父類(lèi) {
}
class 子類(lèi) extends 父類(lèi) {
}
2.作用
1.提高代碼的復(fù)用性
2.子類(lèi)一旦繼承父類(lèi),就有權(quán)訪問(wèn)父類(lèi)中的內(nèi)容
3.子類(lèi)可以進(jìn)行擴(kuò)展谬返,可以定義子類(lèi)中獨(dú)有的內(nèi)容
3.注意
繼承為單繼承機(jī)制之斯,一個(gè)子類(lèi)只能繼承一個(gè)父類(lèi),但可以多實(shí)現(xiàn)
一個(gè)父類(lèi)可以被多個(gè)子類(lèi)繼承
單繼承的優(yōu)點(diǎn):結(jié)構(gòu)和操作簡(jiǎn)單
單繼承缺點(diǎn):不便于后期維護(hù)
4.重寫(xiě)
方法體的重新實(shí)現(xiàn)
4.1 與重載的區(qū)別
重載:
1.同一個(gè)類(lèi)中的多個(gè)方法
2.方法名相同
3.參數(shù)列表不同|方法簽名不同
重寫(xiě):
1.不同的類(lèi)
2.繼承|實(shí)現(xiàn)
3.方法簽名相同
4.2 不能重寫(xiě)的條件
1.被private修飾的成員方法不能被重寫(xiě)
2.被final修飾的成員方法不能被重寫(xiě)
3.被static修飾的成員方法不能被重寫(xiě)
4.3 檢測(cè)是否重寫(xiě)
1.在行號(hào)的位置顯示O↑
2.@Override注解是否報(bào)編譯錯(cuò)誤
4.4重寫(xiě)的條件
1.==:子類(lèi)重寫(xiě)方法與父類(lèi)中的方法簽名完全相同
2.<=:返回值類(lèi)型相同遣铝,基本數(shù)據(jù)類(lèi)型完全相同佑刷,引用類(lèi)型子類(lèi)范圍<=父類(lèi)范圍
3.>=:子類(lèi)訪問(wèn)權(quán)限修飾符>=父類(lèi)訪問(wèn)權(quán)限修飾符
三、多態(tài)
一種事物的多種表現(xiàn)形式
1.前提:
通過(guò)繼承或者實(shí)現(xiàn)的方式
2.多態(tài)調(diào)用:
會(huì)調(diào)用子類(lèi)中的重寫(xiě)方法酿炸,對(duì)子類(lèi)新增不可見(jiàn)
3.調(diào)用成員方法:
編譯看父類(lèi)瘫絮,運(yùn)行找子類(lèi)
4.調(diào)用成員變量:
編譯運(yùn)行看父類(lèi)
多態(tài)引用調(diào)用時(shí),對(duì)子類(lèi)新增成員不可見(jiàn)
5.轉(zhuǎn)型:
5.1向下轉(zhuǎn)型
多態(tài)前提下填硕,想要調(diào)用子類(lèi)的新增內(nèi)容需要向下轉(zhuǎn)型
基本數(shù)據(jù)類(lèi)型
小范圍類(lèi)型 變量 = (小范圍類(lèi)型)大范圍類(lèi)型
引用數(shù)據(jù)類(lèi)型
子類(lèi)類(lèi)型 子類(lèi)類(lèi)對(duì)象 = (子類(lèi)類(lèi)型)父類(lèi)類(lèi)對(duì)象
5.2向上轉(zhuǎn)型
父類(lèi)引用指向子類(lèi)對(duì)象
父類(lèi)類(lèi)型 引用變量 = new 子類(lèi)類(lèi)型();
6.注意
“java.lang.ClassCastException”類(lèi)型轉(zhuǎn)換異常
解決:instanceof:判斷前面的引用指向的對(duì)象是否為后面類(lèi)型的對(duì)象麦萤,或錢(qián)買(mǎi)你的引用是否指向后面類(lèi)型的子類(lèi)對(duì)象。
編譯原則:只檢查錢(qián)買(mǎi)你的引用與后面的類(lèi)型是否在同一繼承體系上廷支,在則通過(guò)频鉴,不在則不通過(guò)