繼承的出現(xiàn)提高了代碼的復用性,并方便開發(fā)。但隨之也有問題,有些類在描述完之后,不想被繼承,或者有些類中的部分方法功能是固定的,不想讓子類重寫。可是當子類繼承了這些特殊類之后,就可以對其中的方法進行重寫,那怎么解決呢?
要解決上述的這些問題,需要使用到一個關鍵字final,final的意思為最終,不可變。final是個修飾符,它可以用來修飾類,類的成員,以及局部變量。
final修飾類不可以被繼承,但是可以繼承其他類。
class Yy {}
final class Fuextends Yy{}//可以繼承Yy類
class Ziextends Fu{}//不能繼承Fu類
final修飾的方法不可以被覆蓋,但父類中沒有被final修飾方法,子類覆蓋/重寫后可以加final。
class Fu {
// final修飾的方法,不可以被覆蓋,但可以繼承使用
public final void method1(){}
public void method2(){}
}
class Ziextends Fu {
//重寫method2方法
public final void method2(){}
}
final修飾的變量稱為常量,這些變量只能賦值一次。
final int i = 20;
i = 30; //賦值報錯,final修飾的變量只能賦值一次
引用類型的變量值為對象地址值,地址值不能更改,但是地址內(nèi)的對象屬性值可以修改。
final Personp =new Person();
Personp2 =new Person();
p =p2;//final修飾的變量p,所記錄的地址值不能改變
p.name ="小明";//可以更改p對象中name屬性值
p不能為別的對象,而p對象中的name或age屬性值可更改。
修飾成員變量,需要在創(chuàng)建對象前賦值,否則報錯。(當沒有顯式賦值時,多個構造方法的均需要為其賦值。)
class Demo {
//直接賦值
final int m = 100;
//final修飾的成員變量,需要在創(chuàng)建對象前賦值,否則報錯。
final int n;
public Demo(){
//可以在創(chuàng)建對象時所調(diào)用的構造方法中,為變量n賦值
n = 2016;
}
}
當在定義類的時候,類中都會有相應的屬性和方法。而屬性和方法都是通過創(chuàng)建本類對象調(diào)用的。當在調(diào)用對象的某個方法時,這個方法沒有訪問到對象的特有數(shù)據(jù)時,方法創(chuàng)建這個對象有些多余。可是不創(chuàng)建對象,方法又調(diào)用不了,這時就會想,那么我們能不能不創(chuàng)建對象,就可以調(diào)用方法呢?
可以的,我們可以通過static關鍵字來實現(xiàn)。static它是靜態(tài)修飾符,一般用來修飾類中的成員。
被static修飾的成員變量屬于類,不屬于這個類的某個對象。(也就是說,多個對象在訪問或修改static修飾的成員變量時,其中一個對象將static成員變量值進行了修改,其他對象中的static成員變量值跟著改變,即多個對象共享同一個static成員變量)
代碼演示:
class Demo {
public static int num = 100;
}
class Test {
public static void main(String[]args) {
Demod1 =new Demo();
Demod2 =new Demo();
d1.num = 200;
System.out.PRintln(d1.num);//結果為200
System.out.println(d2.num);//結果為200
}
}
被static修飾的成員可以并且建議通過類名直接訪問。
訪問靜態(tài)成員的格式:
類名.靜態(tài)成員變量名
類名.靜態(tài)成員方法名(參數(shù))
對象名.靜態(tài)成員變量名 ------不建議使用該方式,會出現(xiàn)警告
對象名.靜態(tài)成員方法名(參數(shù))------不建議使用該方式,會出現(xiàn)警告
靜態(tài)內(nèi)容是優(yōu)先于對象存在,只能訪問靜態(tài),不能使用this/super。靜態(tài)修飾的內(nèi)容存于靜態(tài)區(qū)。
同一個類中,靜態(tài)成員只能訪問靜態(tài)成員
class Demo {
//成員變量
public int num = 100;
//靜態(tài)成員變量
public static int count = 200;
//靜態(tài)方法
public static void method(){
//System.out.println(num);靜態(tài)方法中,只能訪問靜態(tài)成員變量或靜態(tài)成員方法
System.out.println(count);
}
}
開發(fā)中,我們想在類中定義一個靜態(tài)常量,通常使用public static final修飾的變量來完成定義。此時變量名用全部大寫,多個單詞使用下劃線連接。
定義格式:
public static final數(shù)據(jù)類型 變量名 =值;
如下演示:
class Hello {
public static final String SAY_HELLO ="你好java";
public static void method(){
System.out.println("一個靜態(tài)方法");
}
}
當我們想使用類的靜態(tài)成員時,不需要創(chuàng)建對象,直接使用類名來訪問即可。
System.out.println(Hello.SAY_HELLO);//打印
Hello.method();//調(diào)用一個靜態(tài)方法
注意:
接口中的每個成員變量都默認使用public static final修飾。
所有接口中的成員變量已是靜態(tài)常量,由于接口沒有構造方法,所以必須顯示賦值。可以直接用接口名訪問。
interface Inter {
public static final int COUNT = 100;
}
訪問接口中的靜態(tài)變量
Inter.COUNT
3.關于private的描述
了解到封裝在生活的體現(xiàn)之后,又要回到Java中,細說封裝的在Java代碼中的體現(xiàn),先從描述Person說起。
描述人。Person
屬性:年齡。
行為:說話:說出自己的年齡。
class Person {
int age;
Stringname;
public void show() {
System.out.println("age=" +age +",name" +name);
}
}
public class PersonDemo {
public static void main(String[] args) {
//創(chuàng)建Person對象
Person p = new Person();
p.age = -20; //給Person對象賦值
p.name ="人妖";
p.show();//調(diào)用Person的show方法
}
}
通過上述代碼發(fā)現(xiàn),雖然我們用Java代碼把Person描述清楚了,但有個嚴重的問題,就是Person中的屬性的行為可以任意訪問和使用。這明顯不符合實際需求。
可是怎么才能不讓訪問呢?需要使用一個Java中的關鍵字也是一個修飾符private(私有,權限修飾符)。只要將Person的屬性和行為私有起來,這樣就無法直接訪問。
class Person {
private int age;
private Stringname;
public void show() {
System.out.println("age=" +age +",name" +name);
}
}
年齡已被私有,錯誤的值無法賦值,可是正確的值也賦值不了,這樣還是不行,那腫么辦呢?按照之前所學習的封裝的原理,隱藏后,還需要提供訪問方式。只要對外提供可以訪問的方法,讓其他程序訪問這些方法。同時在方法中可以對數(shù)據(jù)進行驗證。
一般對成員屬性的訪問動作:賦值(設置set),取值(獲取get),因此對私有的變量訪問的方式可以提供對應的setXxx或者getXxx的方法。
class Person {
//私有成員變量
private int age;
private Stringname;
//對外提供設置成員變量的方法
public void setAge(int a) {
//由于是設置成員變量的值,這里可以加入數(shù)據(jù)的驗證
if (a < 0 || a > 130) {
System.out.println(a + "不符合年齡的數(shù)據(jù)范圍");
return;
}
age = a;
}
//對外提供訪問成員變量的方法
public void getAge() {
return age;
}
}
總結:
類中不需要對外提供的內(nèi)容都私有化,包括屬性和方法。
以后再描述事物,屬性都私有化,并提供setXxx getXxx方法對其進行訪問。
注意:私有僅僅是封裝的體現(xiàn)形式而已。
新聞熱點
疑難解答