java高级类_Java高级类特性(一)
權(quán)限類內(nèi)同包不同包子類不同包非子類
private
√
×
×
×
default
√
√
×
×
protected
√
√
√
×
public
√
√
√
√
四、super關(guān)鍵字的使用
package com.test.java;
/*
* super可以用來修飾屬性、方法、構(gòu)造器
* 1)當(dāng)子類與父類中有同名的屬性時(shí),可以通過"super.屬性"顯式的調(diào)用父類中聲明的屬性。用"this.屬性"調(diào)用子類中聲明的屬性
* 2)當(dāng)子類重寫父類的方法以后,在子類中想再顯式的調(diào)用父類的被重寫的方法,需要用"super.方法來調(diào)用"
* 3)super修飾構(gòu)造器:通過在子類中使用"super(形參列表)"來顯式的調(diào)用父類的構(gòu)造器
* >在構(gòu)造器內(nèi)部,"super(形參列表)"必須要聲明在首行
* >在構(gòu)造器內(nèi)部,"this.(形參列表)"與"super(形參列表)"只能出現(xiàn)一個
* >當(dāng)構(gòu)造器中,不顯式的調(diào)用this()或者super()其中任何一個,默認(rèn)調(diào)用的是父類的空參構(gòu)造器
* 如果父類沒有聲明空參構(gòu)造器,或者只聲明了帶參數(shù)的構(gòu)造器(這時(shí)空參構(gòu)造器自動作廢),在子類
* 中會報(bào)錯
* 建議:在設(shè)計(jì)一個類時(shí),盡量提供一個空參構(gòu)造器。
*/
public class Person {
public String name;
public Person() {//父類構(gòu)造器
this.name = "Father";
System.out.println(this.name);
}
public void eat() {
System.out.println("父類吃飯");
}
}
class Student extends Person{
public String name;
public Student() {//子類構(gòu)造器,經(jīng)過main方法測試,調(diào)用子類構(gòu)造器之前會自動調(diào)用父類構(gòu)造器
//相當(dāng)于這里有一個 Super();
this.name = "Son";
super.name = "SuperFather";//在子類中調(diào)用父類的
System.out.println(this.name+super.name);
}
public void eat() {
System.out.println("子類吃飯");
super.eat();//在子類中用super調(diào)用父類的重名方法,重寫(覆蓋)并不等于將父類的方法刪除掉。
}
}
五、子類對象實(shí)例化
class Creature{
public Creature(){
System.out.println("Creature無參數(shù)的構(gòu)造器");
}
}
class Animal extends Creature{
public Animal(String name){
System.out.println("Animal帶一個參數(shù)的構(gòu)造器,該動物的name為" + name);
}
public Animal(String name , int age){
this(name);
System.out.println("Animal帶兩個參數(shù)的構(gòu)造器,其age為" + age);
}
}
public class Wolf extends Animal{
public Wolf(){
super("灰太狼", 3);
System.out.println("Wolf無參數(shù)的構(gòu)造器");
}
public static void main(String[] args){
new Wolf();
} }
從創(chuàng)建Wolf對象開始,調(diào)用Wolf構(gòu)造器,Wolf構(gòu)造器調(diào)用父類Animal的兩個參數(shù)的構(gòu)造器,兩個參數(shù)的構(gòu)造器再調(diào)用一個參數(shù)的構(gòu)造器,一個參數(shù)的構(gòu)造器再調(diào)用父類Creature的構(gòu)造器,Creature構(gòu)造器調(diào)用Object類中的構(gòu)造器,然后再逆向執(zhí)行回來,最后一個被調(diào)用的構(gòu)造器最先執(zhí)行,依次向下執(zhí)行構(gòu)造器中的內(nèi)容,像對象中的toString方法等就是再Object類中的某個方法,任何一個類調(diào)用構(gòu)造器都會以最后一個Object類結(jié)束。
六、多態(tài)性
package com.xijian.java;
/*
* 多態(tài)的應(yīng)用舉例
* 總結(jié):通過向上轉(zhuǎn)型來引用父類方法(在子類未重寫方法的前提下),通過向下轉(zhuǎn)型來引用子類獨(dú)有的方法
* 向下轉(zhuǎn)型實(shí)際就是在棧空間聲明一個子類引用類型的變量指向棧空間的父類引用對象,通過父類引用對象進(jìn)而指向堆空間,對對象進(jìn)行操作。
* 訪問權(quán)限是由引用變量類型決定的。
*/
public class TestAnimal {
public static void main(String[] args) {
Animal a = new Dog();//可以擴(kuò)大對象被調(diào)用的權(quán)限
Animal b = new Cat();//可以擴(kuò)大對象被調(diào)用的權(quán)限
TestAnimal test = new TestAnimal();
test.func(a);
test.func(b);
}
public void func(Animal a) {
a.eat();
a.jump();
if(a instanceof Dog) {
Dog d = (Dog)a;//向下轉(zhuǎn)型,用新的引用類型去引用子類存在而父類不存在的方法
d.say();
}
if(a instanceof Cat) {
Cat c = (Cat)a;//向下轉(zhuǎn)型,用新的引用類型去引用子類存在而父類不存在的方法
c.say();
c.name = "1";
System.out.println(a.name);//通過測試可以看出,向下轉(zhuǎn)型使用新的引用類型可以對子類對象進(jìn)行操作
}
}
}
class Animal{
String name;
int age;
public void eat() {
System.out.println("進(jìn)食");
}
public void jump() {
System.out.println("jump");
}
}
class Dog extends Animal{
public void eat() {
System.out.println("狗進(jìn)食");
}
public void jump() {
System.out.println("狗急跳墻");
}
public void say() {
System.out.println("狗叫");
}
}
class Cat extends Animal{
public void eat() {
System.out.println("貓進(jìn)食");
}
public void jump() {
System.out.println("貓?zhí)?#34;);
}
public void say() {
System.out.println("貓叫");
}
}
多態(tài)性:多態(tài)就是指程序中定義的引用變量所指向的具體類型和通過該引用變量發(fā)出的方法調(diào)用在編程時(shí)并不確定,而是在程序運(yùn)行期間才確定,即一個引用變量倒底會指向哪個類的實(shí)例對象,該引用變量發(fā)出的方法調(diào)用到底是哪個類中實(shí)現(xiàn)的方法,必須在由程序運(yùn)行期間才能決定。因?yàn)樵诔绦蜻\(yùn)行時(shí)才確定具體的類,這樣,不用修改源程序代碼,就可以讓引用變量綁定到各種不同的類實(shí)現(xiàn)上,從而導(dǎo)致該引用調(diào)用的具體方法隨之改變,即不修改程序代碼就可以改變程序運(yùn)行時(shí)所綁定的具體代碼,讓程序可以選擇多個運(yùn)行狀態(tài),這就是多態(tài)性。
1)如果我們定義了一個指向子類的父類引用類型,那么它除了能夠引用父類的共性外,還可以使用子類強(qiáng)大的功能,這就是向上轉(zhuǎn)型。
父類名稱 引用對象名稱 = new 子類對象名稱();
指向子類的父類引用由于向上轉(zhuǎn)型了,它只能訪問父類中擁有的方法和屬性,而對于子類中存在而父類中不存在的方法,該引用是不能使用的,盡管是重載該方法。若子類重寫了父類中的某些方法,在調(diào)用該些方法的時(shí)候,必定是使用子類中定義的這些方法(動態(tài)連接、動態(tài)調(diào)用)。()
2)如果在向上轉(zhuǎn)型之后想訪問子類中獨(dú)有的方法,需要向下轉(zhuǎn)型,向下轉(zhuǎn)型實(shí)際就是在棧空間聲明一個子類引用類型的變量指向棧空間的父類引用對象,通過父類引用對象進(jìn)而指向堆空間,對對象進(jìn)行操作。
子類名稱 新引用對象名稱 = (子類名稱)需轉(zhuǎn)型的對象名;
3)子類對象的多態(tài)性,并不適用于屬性!
在調(diào)用屬性的時(shí)候,只是看的是調(diào)用對象的引用類型,如果這個對象的引用類型是父類的,那么調(diào)父類的屬性,如果是個子類的引用類型,則調(diào)子類對應(yīng)的屬性,并不存在多態(tài)性。
4)判斷對象屬于哪種類型的
if(obj instanceof class){}
其返回true情況如下
1.obj是class類的對象
2.obj是class類子類的對象
多態(tài)性在Java上有兩種體現(xiàn)
①方法的重載和重寫:同名方法可以通過形參列表的不同和子父類的繼承關(guān)系來同時(shí)顯示。
②對象的多態(tài)性:子類的對象可以賦給父類/父接口的引用。
七、所有的類的頂級類Object
package com.xijian.java;
public class Testequals {
public static void main(String[] args) {
//==
//1.基本數(shù)據(jù)類型:根據(jù)基本數(shù)據(jù)類型的值判斷是否相等。相等返回true,否則返回false
//注:兩端數(shù)據(jù)類型可以不同,在不同的情況下也可以返回true
int i = 12;
int j = 12;
System.out.println(i==j);//true
char c = 12;
System.out.println(i==c);//true
float f = 12.0F;
System.out.println(i==f);//true
int k = 65;
char a = 'A';
System.out.println(k==a);//true
//2.引用數(shù)據(jù)類型:比較引用類型變量的地址值是否相等。
Object obj1 = new Object();
Object obj2 = new Object();
Object obj3 = new Object();
obj3 = obj1;
System.out.println(obj1==obj2);//false
System.out.println(obj1==obj3);//true
//equals():①只能處理引用類型對象,并且比較的是兩個對象的地址值是否相等
System.out.println(obj1.equals(obj2));
System.out.println(obj1.equals(obj3));
//像String類 包裝類 File類 Date類重寫了Object類里的equals方法
//比較的是兩個對象中的具體內(nèi)容是否相同
String str1 = new String("AA");
String str2 = new String("AA");
System.out.println(str1.equals(str2));//true
}
}
Object是Java中所有類的頂級類。
①在Java中,==表示等于,=表示賦值。
當(dāng)==兩側(cè)比較的是基本數(shù)據(jù)類型時(shí),由基本數(shù)據(jù)類型的值判斷二者是否相等,相等則返回true,不等在返回false。需要注意的是,兩側(cè)的基本數(shù)據(jù)類型即使類型不同,也會返回true,如:int i =65,char j=12;char a ='A';則i==j==a全部返回true。
當(dāng)兩側(cè)是引用數(shù)據(jù)類型時(shí),兩側(cè)比較的是引用變量的地址值,相等返回true,不等返回false。
②equals方法
equals方法只可以處理引用數(shù)據(jù)類型的變量,在object類中,equals方法仍然是比較兩個引用變量的地址值是否相同;所以要想用equals方法比較object類子類的實(shí)體內(nèi)容,就必須要重寫object類的equals方法。
③String類在內(nèi)存中的分析
翻看String類的源代碼我們可以知道:它是不可繼承的(final修飾類),線程安全的(?????),值不可變(兩個成員變量都有final修飾,指針可變),本質(zhì)上是一個字符數(shù)組。
我們知道創(chuàng)建string類對象的時(shí)候,一般由三種方式:
使用關(guān)鍵字new,如:String s1 = new String(“myString”);
直接定義,如:String s1 = “myString”;
串聯(lián)生成,如:String s1 = “my” + “String”
第一種使用關(guān)鍵字new創(chuàng)建的String類對象時(shí),編譯程序回先在字符串常量池中查看有沒有“myString”這個字符串,若有,則在堆中開辟一塊空間存放new出來的實(shí)例,指向常量池中的"myString",在棧中開辟一塊區(qū)域存放s1這個引用變量,指向堆中的new出來的實(shí)例;若沒有,則在常量池中創(chuàng)建一個"myString"字符串。
第二種方式直接定義過程:在程序編譯期,編譯程序先去字符串常量池檢查,是否存在“myString”,如果不存在,則在常量池中開辟一個內(nèi)存空間存放“myString”;如果存在的話,則不用重新開辟空間。然后在棧中開辟一塊空間,命名為“s1”,存放的值為常量池中“myString”的內(nèi)存地址
第三種,改變的不是字符串,而是相當(dāng)于重新創(chuàng)建了一個新的字符串,重新有一個地址值。
相對于new出來的字符串來說,直接賦值的方式效率好,因?yàn)樗辉谧址A砍亻_辟了一個內(nèi)存空間,而new出來的相當(dāng)于開辟了兩個內(nèi)存空間,耗費(fèi)內(nèi)存。
④toString()方法的使用
當(dāng)我們打印一個引用變量的對象時(shí),默認(rèn)會調(diào)用這個對象的toString方法。
如果對象所在的類沒有重寫Object中的toString方法,那么調(diào)用的就是Object中的toString方法,打印出全類名+@+首地址值。
八、包裝類
將8個基礎(chǔ)數(shù)據(jù)類型包裝成類之后,就可以調(diào)用類中的方法來處理這些數(shù)據(jù)了。
基本數(shù)據(jù)類型、包裝類、String類之間的轉(zhuǎn)換問題
原則:轉(zhuǎn)換成誰,去誰里邊找轉(zhuǎn)換方法或者構(gòu)造器。
① 基本數(shù)據(jù)類型和包裝數(shù)據(jù)類型之間的轉(zhuǎn)換:JDK5.0之后加入了自動裝箱和拆箱的功能。
②基本/包裝數(shù)據(jù)類型和String數(shù)據(jù)類型之間的轉(zhuǎn)換
String-->包裝數(shù)據(jù)類型:Integer.parseInt(str)
包裝數(shù)據(jù)類型-->String:i+“ ”
總結(jié)
以上是生活随笔為你收集整理的java高级类_Java高级类特性(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CSDN markdown 数学公式指导
- 下一篇: java注解类型_Java注解类型