黑馬程序員---關(guān)于Java中的內(nèi)部類(lèi)
關(guān)于Java中的內(nèi)部類(lèi)? ? ? ? ? ? ? ? ??
內(nèi)部類(lèi):如果A類(lèi)需要直接訪問(wèn)B類(lèi)中的成員,而B(niǎo)類(lèi)又需要建立A類(lèi)的對(duì)象。這時(shí),為了方便設(shè)計(jì)和訪問(wèn),直接將A類(lèi)定義在B類(lèi)中。就可以了。A類(lèi)就稱為內(nèi)部類(lèi)。內(nèi)部類(lèi)可以直接訪問(wèn)外部類(lèi)中的成員。而外部類(lèi)想要訪問(wèn)內(nèi)部類(lèi),必須要建立內(nèi)部類(lèi)的對(duì)象。
?
1. 成員位置內(nèi)部類(lèi),可以被成員修飾符修飾
? ? 內(nèi)部類(lèi)可以直接使用外部類(lèi)成員
?
//=====================================================
? 調(diào)用內(nèi)部類(lèi)方法三種格式:
? ? 外部類(lèi).內(nèi)部類(lèi) 變量名 = new 外部類(lèi)().new內(nèi)部類(lèi)();
? ? Outer .Inner in = new ?Outer.new Inner();//這種形式很少用。
? ? 內(nèi)部類(lèi),內(nèi)部類(lèi)方法,都是非靜態(tài)
? ? 外部類(lèi).內(nèi)部類(lèi).方法()
? ? 內(nèi)部類(lèi)靜態(tài),內(nèi)部類(lèi)方法靜態(tài)
? ? 外部類(lèi).內(nèi)部類(lèi) 變量 = new 外部類(lèi).內(nèi)部類(lèi)();
? ? 內(nèi)部類(lèi)靜態(tài),內(nèi)部類(lèi)方法非靜態(tài)
/*
? main方法中
? 直接訪問(wèn)內(nèi)部類(lèi)方法
? 第一種格式:
? ? 內(nèi)部類(lèi)是非靜態(tài)修飾的,內(nèi)部類(lèi)的方法也是非靜態(tài)修飾
? ? 通過(guò)外部類(lèi),找到內(nèi)部類(lèi)
?建立外部類(lèi)對(duì)象,建立內(nèi)部類(lèi)對(duì)象
?*外部類(lèi)名.內(nèi)部類(lèi)名 變量 = new 外部類(lèi)對(duì)象().new內(nèi)部類(lèi)對(duì)象()
? 第二種格式:
? ? 內(nèi)部類(lèi)是靜態(tài)的,內(nèi)部類(lèi)方法也是靜態(tài)的
?直接類(lèi)名調(diào)用
?通過(guò)外部類(lèi),找到內(nèi)部類(lèi),內(nèi)部類(lèi)方法
?*外部類(lèi)名.內(nèi)部類(lèi)名.內(nèi)部類(lèi)方法
? 第三種格式:
? ? 內(nèi)部類(lèi)是靜態(tài)的,內(nèi)部類(lèi)方法是非靜態(tài)的
?通過(guò)外部類(lèi),找到內(nèi)部類(lèi),靜態(tài)內(nèi)部類(lèi)
?內(nèi)部類(lèi)對(duì)象,訪問(wèn)方法
?*外部類(lèi)名.內(nèi)部類(lèi)名 變量 = new 外部類(lèi).內(nèi)部類(lèi)對(duì)象()
*/class?Outer{?static?class?Inner?{??public?void?show(){??????????System.out.println("innerclass..show");??}?}}class?InnerClassDemo1{?public?static?void?main(String[]?args)?{?//?Outer.Inner?oi?=?new?Outer().new?Inner();?//?oi.show();?//?Outer.Inner.show();??Outer.Inner?oi?=?new?Outer.Inner();??oi.show();?//?System.out.println("Hello?World!");?}}
?
//=====================================================
? 2. 局部位置內(nèi)部類(lèi)
? ? 運(yùn)行局部位置內(nèi)部類(lèi),必須依靠外部類(lèi)中的方法,這個(gè)方法中創(chuàng)建內(nèi)部類(lèi)對(duì)象
? ? 局部位置內(nèi)部類(lèi),訪問(wèn)局部變量加final,原因是生命周期問(wèn)題
? ? final的方法,巧妙的解決的生命周期
/*
? 內(nèi)部類(lèi),定義在外部類(lèi)的方法中
? 局部位置內(nèi)部類(lèi),局部,私有,靜態(tài)不能修飾
? 調(diào)用abc方法,建立Inner對(duì)象,Inner是show方法的局部位置變量
? show方法要是不運(yùn)行,可能創(chuàng)建Inner對(duì)象嗎
? 在show方法中,創(chuàng)建Inner對(duì)象
? 內(nèi)部類(lèi)的方法,訪問(wèn)局部變量,局部變量必須加final修飾
? 為什么,生命周期
? show方法進(jìn)棧,帶著變量x一起進(jìn)棧
? 運(yùn)行完畢了,show出棧,變量x死亡
? Inner是一個(gè)類(lèi),創(chuàng)建對(duì)象的,
? 如果show方法死亡,Inner還有可能有對(duì)象存在
? 對(duì)象調(diào)用abc 變量x已經(jīng)死亡
? 第一種說(shuō)
? ? 加final后,變量,變成常量,存儲(chǔ)位置發(fā)生了變化
?常量池 'a' 12 生命最長(zhǎng)的
?即使show出棧后,變量,還在常量池
? 第二種說(shuō)
? ? 變量加上final后,生命周期沒(méi)有改變
?跟著show的存在而存在,消失而消失
?x終身已經(jīng)固定了,因此javac編譯
? ? 生成的class文件,abc方法中,寫(xiě)進(jìn)去了abc2
*/
class Outer
{
?public void show(){
? ?final int x = 3;
? ?class Inner
? ? {
? ? public void abc(){
? ? ? System.out.println("Inner...abc"+x);
? ? }
? ? }
? ?new Inner().abc();
?}
}
class InnerClassDemo3
{
?public static void main(String[] args)
?{
? new Outer().show();
?// System.out.println("Hello World!");
?}
}
//=====================================================
? 3. 匿名內(nèi)部了
? ? 匿名內(nèi)部類(lèi),是一種簡(jiǎn)化形式,簡(jiǎn)化子類(lèi)或者實(shí)現(xiàn)類(lèi)的一種寫(xiě)法
? ? 格式:
? ? ? new 接口或者父類(lèi)(){
? ? ? ? 重寫(xiě)方法
? ? ? }.方法();
? ? ? 接口或者父類(lèi) 變量 = new 接口或者父類(lèi)(){
? ? ? ? 重寫(xiě)多個(gè)方法
? ? ? };
? ? ? 變量.方法();
? ? ? 變量.方法();
abstract class Animal
{
?public abstract void eat();
}
class NiMingTest
{
?public static void main(String[] args)
?{
? //調(diào)用eat方法
? new Animal(){
? ? ?public void eat(){
? ? ? ?System.out.println("貓吃魚(yú)");
? ? ?}
? }.eat();
?}
}
//==============//=====================================================
interface MSFace
{
?void windows();
}
class Sun
{
?//補(bǔ)齊代碼,程序可以編譯運(yùn)行
?public static MSFace getMs(){
? //返回值是一個(gè)接口類(lèi)型,那么,肯定return子類(lèi)對(duì)象
? ? return new MSFace(){
? ? public void windows(){
? ? ? System.out.println("windows nt6.1");
? ? }
? };
?}
}
class NiMingTest1
{
?public static void main(String[] args)
?{
? //接口 = 類(lèi).方法
? MSFace ms = Sun.getMs();
? ms.windows();
?}
}
//=====================================================
interface A
{
?public abstract void function();
?public abstract void function2();
}
/*class AImpl implements A
{
?public void function(){
?
?}
?public void function2(){
?
?}
}*/
class Outer
{
?public void show(){
? ?//匿名內(nèi)部類(lèi),就是實(shí)現(xiàn)接口和重寫(xiě)方法的簡(jiǎn)化形式
? ?//格式: new 接口 不是以分號(hào)結(jié)束,是以大括號(hào)結(jié)束的,大括號(hào)中,重寫(xiě)抽象方法
? A a = new A(){
? ? ? public void function(){
? ? ? ?System.out.println("匿名內(nèi)部類(lèi)...function");
? ?}
? ?public void function2(){
? ? ? ?System.out.println("匿名內(nèi)部類(lèi)...function22222");
? ?}
? ?};
? ?a.function();
? ?a.function2();
? ?//以上一段代碼,看成是A接口的實(shí)現(xiàn)類(lèi)的對(duì)象
?}
}
class NiMingClass
{
?public static void main(String[] args)
?{
? new Outer().show();
? //System.out.println("Hello World!");
?}
}
//=====================================================
/*
? 內(nèi)部類(lèi),實(shí)現(xiàn)接口
? 從main中,調(diào)用內(nèi)部類(lèi)的show方法
? 分析:內(nèi)部類(lèi),私有的,不能直接通過(guò)外部類(lèi)獲得內(nèi)部類(lèi)
? 在外部類(lèi),提供我一個(gè)公共方法,可以返回內(nèi)部類(lèi)的對(duì)象呢
? 多態(tài)機(jī)制
*/
interface Face
{
?void show();
}
class Outer
{
?private class Inner implements Face
?{
? public void show(){
? ? ?System.out.println("內(nèi)部類(lèi)重寫(xiě)接口方法");
? }
?}
? ? //返回值,返回的是接口類(lèi)型,其實(shí)返回的是接口的實(shí)現(xiàn)類(lèi)對(duì)象
?//實(shí)現(xiàn)類(lèi),私有的內(nèi)部類(lèi)
?public Face getInner(){
? ? return new Inner();
?}
}
class InnerClassDemo2
{
?public static void main(String[] args)
?{
? Outer o = new Outer();
? //Face接口,指向自己的實(shí)現(xiàn)類(lèi)對(duì)象,實(shí)現(xiàn)類(lèi)對(duì)象,沒(méi)有直接new,通過(guò)getInnerf方法獲取的
? Face x = o.getInner();
? in.show();
?}
}
? ? ? ? ? ? ? ? ??