Java内部类的定义和使用
為什么要用到內(nèi)部類(lèi):
在java開(kāi)發(fā)學(xué)習(xí)中我們經(jīng)常會(huì)碰到內(nèi)部類(lèi)。內(nèi)部類(lèi)又有很多的優(yōu)勢(shì):首先舉一個(gè)簡(jiǎn)單的例子,如果你想實(shí)現(xiàn)一個(gè)接口,但是這個(gè)接口中的一個(gè)方法和你構(gòu)想的這個(gè)類(lèi)中的一個(gè)方法名稱(chēng)參數(shù)相同,你應(yīng)該怎么辦?這時(shí)候,你可以建一個(gè)內(nèi)部類(lèi)實(shí)現(xiàn)這個(gè)接口。由于內(nèi)部類(lèi)對(duì)外部類(lèi)的所有內(nèi)容都是可訪問(wèn)的,所以這樣做可以完成所有你直接實(shí)現(xiàn)這個(gè)接口的功能。不過(guò)你可能要質(zhì)疑,更改一下方法的不就行了嗎?的確,以此作為設(shè)計(jì)內(nèi)部類(lèi)的理由,實(shí)在沒(méi)有說(shuō)服力。真正的原因是這樣的,java中的內(nèi)部類(lèi)和接口加在一起,從而java 通過(guò)內(nèi)部類(lèi)加上接口,可以很好的實(shí)現(xiàn)多繼承的效果。
?
內(nèi)部類(lèi)的分類(lèi)和使用
1、成員內(nèi)部類(lèi): 即作為外部類(lèi)的一個(gè)成員存在,與外部類(lèi)的屬性、方法并列。注意:成員內(nèi)部類(lèi)中不能定義靜態(tài)變量,但可以訪問(wèn)外部類(lèi)的所有成員。值得注意的是成員內(nèi)部類(lèi)編譯成功后會(huì)生成的兩個(gè)不同的類(lèi)(.class) 成員內(nèi)部類(lèi)的優(yōu)點(diǎn): 1)、內(nèi)部類(lèi)作為外部類(lèi)的成員,可以訪問(wèn)外部類(lèi)的私有成員或?qū)傩浴?#xff08;即使將外部類(lèi)聲明為PRIVATE,但是對(duì)于處于其內(nèi)部的內(nèi)部類(lèi)還是可見(jiàn)的。) 2)、用內(nèi)部類(lèi)定義在外部類(lèi)中不可訪問(wèn)的屬性。這樣就在外部類(lèi)中實(shí)現(xiàn)了比外部類(lèi)的private還要小的訪問(wèn)權(quán)限。 package one;public class Outer{private static int outer_i = 1;private int k=20;public static void outer1(){//... }//成員內(nèi)部類(lèi)class Inner{int j=100;//內(nèi)部類(lèi)中外部類(lèi)的實(shí)例變量可以共存int inner_i=1;void inner1(){System.out.println(outer_i);//外部類(lèi)的變量如果和內(nèi)部類(lèi)的變量沒(méi)有同名的,則可以直接用變量名訪問(wèn)外部類(lèi)的變量System.out.println(j);//在內(nèi)部類(lèi)中訪問(wèn)內(nèi)部類(lèi)自己的變量直接用變量名System.out.println(this.j);//也可以在內(nèi)部類(lèi)中用"this.變量名"來(lái)訪問(wèn)內(nèi)部類(lèi)變量//訪問(wèn)外部類(lèi)中與內(nèi)部類(lèi)同名的實(shí)例變量可用"外部類(lèi)名.this.變量名"。System.out.println(k);//外部類(lèi)的變量如果和內(nèi)部類(lèi)的變量沒(méi)有同名的,則可以直接用變量名訪問(wèn)外部類(lèi)的變量 outer1();}}//外部類(lèi)的非靜態(tài)方法訪問(wèn)成員內(nèi)部類(lèi)public void outer2(){Inner inner = new Inner();inner.inner1();}//外部類(lèi)的靜態(tài)方法訪問(wèn)成員內(nèi)部類(lèi),與在外部類(lèi)外部訪問(wèn)成員內(nèi)部類(lèi)一樣public static void outer3(){Outer out = new Outer();//step1 建立外部類(lèi)對(duì)象Inner inner=out.new Inner();//step2 根據(jù)外部類(lèi)對(duì)象建立內(nèi)部類(lèi)對(duì)象inner.inner1();//step3 訪問(wèn)內(nèi)部類(lèi)的方法 }public static void main(String[] args){outer3();} }?
2、局部?jī)?nèi)部類(lèi): 即在方法中定義的內(nèi)部類(lèi),與局部變量類(lèi)似,在局部?jī)?nèi)部類(lèi)前不加修飾符public或private,其范圍為定義它的代碼塊。
?
public class Outer {public void say(){System.out.println("關(guān)門(mén)說(shuō)真話!");} } public class Test {public void ting(){class MiMi extends Outer{//定義一個(gè)局部的內(nèi)部類(lèi),繼承Outer方法//…… }new MiMi().say();//調(diào)用局部?jī)?nèi)部類(lèi)中繼承的say方法 System.out.println("別人都不知道");}public static void main(String[] args) {new Test().ting();} }?
3、靜態(tài)內(nèi)部類(lèi): 靜態(tài)內(nèi)部類(lèi)定義在類(lèi)中,任何方法外,用static定義。注意:靜態(tài)內(nèi)部類(lèi)中可以定義靜態(tài)或者非靜態(tài)的成員
package three;public class StaticTest { private static String name="abc";private String sex="男";static class Person{private String age = "18";//內(nèi)部私有成員public String heigth = "180";//內(nèi)部類(lèi)公有成員public void display(){//System.out.println(sex);//報(bào)錯(cuò),不能直接訪問(wèn)外部類(lèi)的非靜態(tài)成員System.out.println(name);//只能直接訪問(wèn)外部類(lèi)的靜態(tài)成員System.out.println(age);//訪問(wèn)本內(nèi)部類(lèi)成員。 } }public void testone(){Person person = new Person();person.display();//System.out.println(heigth);//報(bào)錯(cuò),是因?yàn)椴豢梢灾苯釉L問(wèn)內(nèi)部類(lèi)私有成員//System.out.println(age);//報(bào)錯(cuò),是因?yàn)椴豢梢灾苯釉L問(wèn)內(nèi)部類(lèi)公有成員System.out.println(person.age);//可以訪問(wèn)內(nèi)部類(lèi)的私有成員System.out.println(person.heigth);//可以訪問(wèn)內(nèi)部類(lèi)的公有成員 } public void testtwo(){StaticTest st = new StaticTest();System.out.println(name);System.out.println(sex);//System.out.println(age);//不可以直接訪問(wèn)內(nèi)部類(lèi)的成員//System.out.println(heigth);//不可以直接訪問(wèn)內(nèi)部類(lèi)的成員 }public static void main(String[] args) { //調(diào)用StaticTestStaticTest staticTest = new StaticTest(); staticTest.testone(); staticTest.testtwo();} } 4、匿名內(nèi)部類(lèi): 匿名內(nèi)部類(lèi)是在抽象類(lèi)和接口的基礎(chǔ)之上發(fā)展起來(lái)的。匿名內(nèi)部類(lèi)如果繼承自接口,必須實(shí)現(xiàn)指定接口的方法,且無(wú)參數(shù) 。匿名內(nèi)部類(lèi)如果繼承自類(lèi),參數(shù)必須按父類(lèi)的構(gòu)造函數(shù)的參數(shù)傳遞 匿名內(nèi)部類(lèi)的特點(diǎn): 1),一個(gè)類(lèi)用于繼承其他類(lèi)或是實(shí)現(xiàn)接口,并不需要增加額外的方法,只是對(duì)繼承方法的事先或是覆蓋。 2),只是為了獲得一個(gè)對(duì)象實(shí)例,不需要知道其實(shí)際類(lèi)型。 3),類(lèi)名沒(méi)有意義,也就是不需要使用到。 package three;abstract class parent {public abstract void like(); }public class Demo {public static void main(String[] args) {parent pt = new parent(){public void like(){System.out.println("吃飯睡覺(jué)打豆豆。。。");}};pt.like();} }?
匿名類(lèi)與內(nèi)部的聯(lián)系與區(qū)別:
? 按所在位置可以分為兩大類(lèi): 1、在類(lèi)的方法中 特點(diǎn): a、可以訪問(wèn)宿主類(lèi)的所有元素 ; b、保存宿主類(lèi)對(duì)象的引用,創(chuàng)建對(duì)象時(shí)必須有宿主類(lèi)對(duì)象; c、 不能有靜態(tài)數(shù)據(jù); 繼續(xù)劃分: A、本地內(nèi)部類(lèi); B、匿名內(nèi)部類(lèi) 兩者的區(qū)別在于本地內(nèi)部類(lèi)有構(gòu)造方法,而匿名內(nèi)部類(lèi)只能實(shí)例初始化; 2、在類(lèi)或接口作用域中; A、普通內(nèi)部類(lèi) B、靜態(tài)內(nèi)部類(lèi)?
內(nèi)部類(lèi)總結(jié):
1.內(nèi)部類(lèi)作為外部類(lèi)的一個(gè)特殊的成員來(lái)看待,因此它有類(lèi)成員的封閉等級(jí):private ,protected,默認(rèn)(friendly),public 它有類(lèi)成員的修飾符: ??static,final,abstract 2.非靜態(tài)內(nèi)部類(lèi)nested inner class,內(nèi)部類(lèi)隱含有一個(gè)外部類(lèi)的指針this,因此,它可以訪問(wèn)外部類(lèi)的一切資源(當(dāng)然包括private)外部類(lèi)訪問(wèn)內(nèi)部類(lèi)的成員,先要取得內(nèi)部類(lèi)的對(duì)象,并且取決于內(nèi)部類(lèi)成員的封裝等級(jí)。非靜態(tài)內(nèi)部類(lèi)不能包含任何static成員. 3.靜態(tài)內(nèi)部類(lèi):static inner class,不再包含外部類(lèi)的this指針,并且在外部類(lèi)裝載時(shí)初始化. 靜態(tài)內(nèi)部類(lèi)只能訪問(wèn)外部類(lèi)static成員. 外部類(lèi)訪問(wèn)靜態(tài)內(nèi)部類(lèi)的成員:static成員:類(lèi)名.成員;非static成員:對(duì)象.成員 4.對(duì)于方法中的內(nèi)部類(lèi)或塊中內(nèi)部類(lèi)只能訪問(wèn)塊中或方法中的final變量。轉(zhuǎn)載于:https://www.cnblogs.com/xiao-chuan/p/6014752.html
總結(jié)
以上是生活随笔為你收集整理的Java内部类的定义和使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【洛谷P1966】火柴排队
- 下一篇: spring管理的类如何调用非sprin