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