整理java讀書(shū)筆記十五之java中的內(nèi)部類(lèi)
內(nèi)部類(lèi)是指在一個(gè)外部類(lèi)的內(nèi)部再定義一個(gè)類(lèi)。類(lèi)名不需要和文件夾相同。
*內(nèi)部類(lèi)可以是靜態(tài)static的,也可用public,default,protected和private修飾。(而外部頂級(jí)類(lèi)即類(lèi)名和文件名相同的只能使用public和default)。
前言
Java從JDK1.1的時(shí)候,就開(kāi)始引入內(nèi)部類(lèi)的概念了,那么小編也通過(guò)這篇博客來(lái)分享一下Java中有關(guān)內(nèi)部類(lèi)的一些特性。
什么是內(nèi)部類(lèi)?
在很多情況下,類(lèi)被定義成一個(gè)獨(dú)立的程序單元,但是有時(shí)候也會(huì)把一個(gè)類(lèi)放在另一個(gè)類(lèi)的內(nèi)部定義,這個(gè)定義在其他類(lèi)內(nèi)部的類(lèi)就稱(chēng)為內(nèi)部類(lèi)。
從語(yǔ)法上來(lái)看的話(huà),定義內(nèi)部類(lèi)和定義外部類(lèi)的語(yǔ)法大致相同,內(nèi)部類(lèi)除了需要定義在其他類(lèi)里面之外,還存在如下兩點(diǎn)區(qū)別。
1.內(nèi)部類(lèi)比外部類(lèi)多使用三個(gè)修飾符:private——protected、static——外部類(lèi)不可以使用這三個(gè)修飾符。
2.非靜態(tài)內(nèi)部類(lèi)不能擁有靜態(tài)成員。
除了以上兩點(diǎn)之外,其他的地方都與普通的類(lèi)相同,下面來(lái)列舉一下常見(jiàn)的內(nèi)部類(lèi)操作。
非靜態(tài)內(nèi)部類(lèi)
定義內(nèi)部類(lèi)也非常簡(jiǎn)單,只要把一個(gè)類(lèi)放在另一個(gè)類(lèi)內(nèi)部定義即可,甚至都可以放置在方法的內(nèi)部。
<span style="font-family:Comic Sans MS;font-size:18px;">package com.test;
public class Cow
{
private double weight;
// 外部類(lèi)的兩個(gè)重載的構(gòu)造器
public Cow(){}
public Cow(double weight)
{
this.weight = weight;
}
// 定義一個(gè)非靜態(tài)內(nèi)部類(lèi)
private class CowLeg
{
// 非靜態(tài)內(nèi)部類(lèi)的兩個(gè)實(shí)例變量
private double length;
private String color;
// 非靜態(tài)內(nèi)部類(lèi)的兩個(gè)重載的構(gòu)造器
public CowLeg(){}
public CowLeg(double length , String color)
{
this.length = length;
this.color = color;
}
// 下面省略length、color的setter和getter方法
public void setLength(double length)
{
this.length = length;
}
public double getLength()
{
return this.length;
}
public void setColor(String color)
{
this.color = color;
}
public String getColor()
{
return this.color;
}
// 非靜態(tài)內(nèi)部類(lèi)的實(shí)例方法
public void info()
{
System.out.println("當(dāng)前牛腿顏色是:"
+ color + ", 高:" + length);
// 直接訪(fǎng)問(wèn)外部類(lèi)的private修飾的成員變量
System.out.println("本牛腿所在奶牛重:" + weight); //①
}
}
public void test()
{
CowLeg cl = new CowLeg(1.12 , "黑白相間");
cl.info();
}
public static void main(String[] args)
{
Cow cow = new Cow(378.9);
cow.test();
}
}
</span>
在上述中非靜態(tài)內(nèi)部類(lèi)的成員可以訪(fǎng)問(wèn)外部類(lèi)的private成員,但反過(guò)來(lái)就不成立了。非靜態(tài)內(nèi)部類(lèi)的成員只在非靜態(tài)內(nèi)部類(lèi)范圍內(nèi)是可知的,并不能被外部類(lèi)直接使用。如果外部類(lèi)需要訪(fǎng)問(wèn)非靜態(tài)內(nèi)部類(lèi)的成員,則必須顯式創(chuàng)建非靜態(tài)內(nèi)部類(lèi)對(duì)象來(lái)調(diào)用訪(fǎng)問(wèn)其實(shí)例成員。
<span style="font-family:Comic Sans MS;font-size:18px;">package com.test;
public class Outer
{
private int outProp = 9;
class Inner
{
private int inProp = 5;
public void acessOuterProp()
{
// 非靜態(tài)內(nèi)部類(lèi)可以直接訪(fǎng)問(wèn)外部類(lèi)的private成員變量
System.out.println("外部類(lèi)的outProp值:"
+ outProp);
}
}
public void accessInnerProp()
{
// 外部類(lèi)不能直接訪(fǎng)問(wèn)非靜態(tài)內(nèi)部類(lèi)的實(shí)例變量,
// 下面代碼出現(xiàn)編譯錯(cuò)誤
// System.out.println("內(nèi)部類(lèi)的inProp值:" + inProp);
// 如需訪(fǎng)問(wèn)內(nèi)部類(lèi)的實(shí)例變量,必須顯式創(chuàng)建內(nèi)部類(lèi)對(duì)象
System.out.println("內(nèi)部類(lèi)的inProp值:"
+ new Inner().inProp);
}
public static void main(String[] args)
{
// 執(zhí)行下面代碼,只創(chuàng)建了外部類(lèi)對(duì)象,還未創(chuàng)建內(nèi)部類(lèi)對(duì)象
Outer out = new Outer(); //①
out.accessInnerProp();
}
}
</span>
注意:非靜態(tài)內(nèi)部類(lèi)中不能有靜態(tài)方法、靜態(tài)成員變量、靜態(tài)初始化塊。
靜態(tài)內(nèi)部類(lèi)
如果使用static來(lái)修飾一個(gè)內(nèi)部類(lèi),則這個(gè)內(nèi)部類(lèi)就屬于外部類(lèi)本身,而不屬于外部類(lèi)的某個(gè)對(duì)象,因此使用static修飾的內(nèi)部類(lèi)被稱(chēng)為類(lèi)內(nèi)部類(lèi),有的地方也稱(chēng)為靜態(tài)內(nèi)部類(lèi)。靜態(tài)內(nèi)部類(lèi)可以包含靜態(tài)成員,也可以包含非靜態(tài)成員。根據(jù)靜態(tài)成員不能訪(fǎng)問(wèn)非靜態(tài)成員的規(guī)則,靜態(tài)內(nèi)部類(lèi)不能訪(fǎng)問(wèn)外部類(lèi)的實(shí)例成員,只能訪(fǎng)問(wèn)外部類(lèi)的類(lèi)成員。
<span style="font-family:Comic Sans MS;font-size:18px;">package com.test;
public class StaticInnerClassTest
{
private int prop1 = 5;
private static int prop2 = 9;
static class StaticInnerClass
{
// 靜態(tài)內(nèi)部類(lèi)里可以包含靜態(tài)成員
private static int age;
public void accessOuterProp()
{
// 下面代碼出現(xiàn)錯(cuò)誤:
// 靜態(tài)內(nèi)部類(lèi)無(wú)法訪(fǎng)問(wèn)外部類(lèi)的實(shí)例變量
System.out.println(prop1);
// 下面代碼正常
System.out.println(prop2);
}
}
}
</span>
匿名內(nèi)部類(lèi)
使用匿名內(nèi)部類(lèi)可以創(chuàng)建那種只需要一次使用的類(lèi),并且創(chuàng)建匿名內(nèi)部類(lèi)時(shí)會(huì)立即創(chuàng)建一個(gè)該類(lèi)的實(shí)例,但是也需要注意一下規(guī)則
1.匿名內(nèi)部類(lèi)不能是抽象類(lèi),因?yàn)橄到y(tǒng)在創(chuàng)建匿名內(nèi)部類(lèi)時(shí),會(huì)立即創(chuàng)建匿名內(nèi)部類(lèi)的對(duì)象,因此不允許將匿名內(nèi)部類(lèi)定義成為抽象類(lèi)
2.匿名內(nèi)部類(lèi)不能定義構(gòu)造器,由于匿名內(nèi)部類(lèi)沒(méi)有類(lèi)名,所以無(wú)法定義構(gòu)造器
<span style="font-family:Comic Sans MS;font-size:18px;">package com.test;
interface Product
{
public double getPrice();
public String getName();
}
public class AnonymousTest
{
public void test(Product p)
{
System.out.println("購(gòu)買(mǎi)了一個(gè)" + p.getName()
+ ",花掉了" + p.getPrice());
}
public static void main(String[] args)
{
AnonymousTest ta = new AnonymousTest();
// 調(diào)用test()方法時(shí),需要傳入一個(gè)Product參數(shù),
// 此處傳入其匿名實(shí)現(xiàn)類(lèi)的實(shí)例
ta.test(new Product()
{
public double getPrice()
{
return 567.8;
}
public String getName()
{
return "AGP顯卡";
}
});
}
}
</span>
下面給大家總結(jié)以下內(nèi)部類(lèi)的共性編輯
(1)、內(nèi)部類(lèi)仍然是一個(gè)獨(dú)立的類(lèi),在編譯之后內(nèi)部類(lèi)會(huì)被編譯成獨(dú)立的.class文件,但是前面冠以外部類(lèi)的類(lèi)名和$符號(hào) 。
(2)、內(nèi)部類(lèi)不能用普通的方式訪(fǎng)問(wèn)。內(nèi)部類(lèi)是外部類(lèi)的一個(gè)成員,因此內(nèi)部類(lèi)可以自由地訪(fǎng)問(wèn)外部類(lèi)的成員變量,無(wú)論是否是private的 。
(3)、內(nèi)部類(lèi)聲明成靜態(tài)的,就不能隨便的訪(fǎng)問(wèn)外部類(lèi)的成員變量了,此時(shí)內(nèi)部類(lèi)只能訪(fǎng)問(wèn)外部類(lèi)的靜態(tài)成員變量 。
相關(guān)文章
SpringBoot中定時(shí)任務(wù)的使用方法解析
這篇文章主要介紹了SpringBoot中定時(shí)任務(wù)的使用方法解析,@EnableScheduling?注解,它的作用是發(fā)現(xiàn)注解?@Scheduled的任務(wù)并由后臺(tái)執(zhí)行,沒(méi)有它的話(huà)將無(wú)法執(zhí)行定時(shí)任務(wù),需要的朋友可以參考下2024-01-01
MyBatis實(shí)現(xiàn)字段加解密的實(shí)踐
為了數(shù)據(jù)安全問(wèn)題,有時(shí)候需要將部分敏感字段加密后再入庫(kù),本文主要介紹了MyBatis實(shí)現(xiàn)字段加解密的實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下2023-11-11
java讀取properties文件的方法實(shí)例分析
這篇文章主要介紹了java讀取properties文件的方法,實(shí)例分析了java讀取在項(xiàng)目中與不在項(xiàng)目中properties文件的相關(guān)技巧,需要的朋友可以參考下2015-06-06
SpringBoot后端接收數(shù)組對(duì)象的實(shí)現(xiàn)
這篇文章主要介紹了SpringBoot后端接收數(shù)組對(duì)象的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11
Service層異常拋到Controller層處理還是直接處理問(wèn)題分析
這篇文章主要為大家介紹了Service層異常拋到Controller層處理還是直接處理的問(wèn)題分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
詳解Java線(xiàn)程池的使用(7種創(chuàng)建方法)
這篇文章主要介紹了詳解Java線(xiàn)程池的使用(7種創(chuàng)建方法),線(xiàn)程池的創(chuàng)建?式總共包含7種,其中6種是通過(guò)Executors創(chuàng)建的,1種是通過(guò)ThreadPoolExecutor創(chuàng)建的,今天我們就來(lái)詳細(xì)說(shuō)一下2023-03-03

