在普通類(lèi)中使用內(nèi)部結(jié)構(gòu)
不多說(shuō),先上個(gè)代碼
Outer類(lèi)里面有個(gè)內(nèi)部類(lèi)Inner
public class Outer {
private String msg = "哈哈"; //只能在類(lèi)內(nèi)部訪問(wèn)
public void fun(){
Inner in = new Inner(); //實(shí)例化內(nèi)部類(lèi)的對(duì)象
in.print();
}
//在Outer類(lèi)中的內(nèi)部類(lèi)
class Inner{
public void print(){
System.out.println(Outer.this.msg); //msg是Outer類(lèi)里面的屬性
}
}
}
測(cè)試類(lèi)
public class Test {
public static void main(String[] args) {
Outer outer = new Outer();
outer.fun();
}
}
創(chuàng)建外部類(lèi)的實(shí)例調(diào)用外部類(lèi)的方法卻執(zhí)行了內(nèi)部類(lèi)的方法,打印出“哈哈”。
從整體的代碼結(jié)構(gòu)來(lái)講,內(nèi)部類(lèi)的結(jié)構(gòu)并不合理,所以內(nèi)部類(lèi)本身最大的缺陷在于破壞了程序的結(jié)構(gòu),但是破壞需要有目的的破壞,那么它也一定會(huì)有其優(yōu)勢(shì),如果要想更好的觀察出內(nèi)部類(lèi)的優(yōu)勢(shì),就可以將內(nèi)部類(lèi)拿到外面來(lái)。我將上面的代碼Inner拿出來(lái)
public class Outer {
private String msg = "哈哈"; //只能在類(lèi)內(nèi)部訪問(wèn)
public void fun(){
Inner in = new Inner(this); //實(shí)例化內(nèi)部類(lèi)的對(duì)象
in.print();
}
public String getMsg(){
return this.msg;
}
}
public class Inner {
private Outer out;
public Inner(Outer out){
this.out = out;
}
public void print(){
System.out.println(this.out.getMsg()); //msg是Outer類(lèi)里面的屬性
}
}
public class Test {
public static void main(String[] args) {
Outer outer = new Outer();
outer.fun();
}
}
如果不是對(duì)引用知識(shí)掌握的比較扎實(shí),會(huì)有點(diǎn)懵。我們折騰了半天主要的目的就是為了讓Inner這個(gè)內(nèi)部類(lèi)可以訪問(wèn)Outer這個(gè)類(lèi)中的私有屬性,如果不用內(nèi)部類(lèi)的時(shí)候整體代碼會(huì)非常的麻煩,所以可以得出內(nèi)部類(lèi)的優(yōu)點(diǎn): 輕松的訪問(wèn)外部類(lèi)中的私有屬性 。
需要注意的是, 內(nèi)部類(lèi)雖然可以方便的訪問(wèn)外部類(lèi)中的私有成員或私有方法 ,同理, 外部類(lèi)也可以輕松訪問(wèn)內(nèi)部類(lèi)中的私有成員或私有方法 。如下
public class Outer {
private String msg = "哈哈";
public void fun(){
Inner in = new Inner();
in.print();
System.out.println(in.info); //訪問(wèn)內(nèi)部類(lèi)的私有屬性
}
class Inner{
private String info = "今天天氣不好";
public void print(){
System.out.println(Outer.this.msg);
}
}
}
使用了內(nèi)部類(lèi)之后,內(nèi)部類(lèi)與外部類(lèi)之間的私有操作的訪問(wèn)就不再需要通過(guò)setter,getter以及其他的間接方式完成了,可以直接進(jìn)行操作,但是需要注意的是,內(nèi)部類(lèi)本身也屬于一個(gè)類(lèi),雖然在大部分情況下內(nèi)部類(lèi)往往是被外部類(lèi)包裹的,但是外部依然可以產(chǎn)生內(nèi)部類(lèi)的實(shí)例化對(duì)象,而此時(shí),內(nèi)部類(lèi)實(shí)例化對(duì)象的格式如下:
外部類(lèi).內(nèi)部類(lèi) 內(nèi)部類(lèi)對(duì)象 = new 外部類(lèi)().new 內(nèi)部類(lèi)() ;
在內(nèi)部類(lèi)編譯完成之后會(huì)自動(dòng)形成一個(gè)“Outer”這個(gè)符號(hào)換到程序中就變?yōu)椤?”,所以 內(nèi)部類(lèi)的全稱(chēng):“外部類(lèi).內(nèi)部類(lèi)” 。內(nèi)部類(lèi)與外部類(lèi)之間可以直接進(jìn)行私有成員的訪問(wèn),這樣一來(lái)內(nèi)部類(lèi)如果要是提供有實(shí)例化對(duì)象了,一定要先保證外部類(lèi)實(shí)例化了。
public class Test {
public static void main(String[] args) {
Outer.Inner in = new Outer().new Inner();
in.print();
}
}
如果此時(shí)Inner類(lèi)只允許Outer類(lèi)來(lái)使用,那么在這樣的情況下就可以使用private進(jìn)行私有定義 。
這樣,此時(shí)的Inner類(lèi)就無(wú)法再外部使用, 即在test中的這條語(yǔ)句 Outer.Inner in = new Outer().new Inner()就失效 。
2. 在抽象類(lèi)和接口中使用內(nèi)部結(jié)構(gòu)
在我們的java之中,類(lèi)作為最基礎(chǔ)的結(jié)構(gòu)體實(shí)際上還有與之類(lèi)似的抽象類(lèi)或者是接口,抽象類(lèi)和接口中都可以定義內(nèi)部結(jié)構(gòu)。
2.1 接口中定義內(nèi)部接口
我們現(xiàn)在定義 內(nèi)部接口 :
public interface IChannel {
public void send(IMessage msg);
//內(nèi)部接口
interface IMessage{
public String getContent();
}
}
public class ChannelImpl implements IChannel {
@Override
public void send(IMessage msg) {
System.out.println(msg.getContent());
}
class MessageImpl implements IMessage{
@Override
public String getContent() {
return "haha";
}
}
}
public class Test {
public static void main(String[] args) {
IChannel channel = new ChannelImpl();
channel.send(((ChannelImpl)channel).new MessageImpl());
}
}
最后打印出結(jié)果 “哈哈”
2.2 接口中定義內(nèi)部抽象類(lèi)
下面我們繼續(xù)觀察一個(gè) 內(nèi)部抽象類(lèi) ,內(nèi)部抽象類(lèi)可以定義在普通類(lèi),抽象類(lèi),接口內(nèi)部都可以
public interface IChannel {
public void send();
abstract class AbstractMessage{
public abstract String getContent();
}
}
public class ChannelImpl implements IChannel {
@Override
public void send() {
AbstractMessage msg = new MessageImpl() ;
System.out.println(msg.getContent());
}
class MessageImpl extends AbstractMessage {
public String getContent() {
return "哈哈";
}
}
}
public class Test {
public static void main(String[] args) {
IChannel channel = new ChannelImpl();
channel.send();
}
}
結(jié)果打印出來(lái)的是“哈哈”。
2.3 用內(nèi)部類(lèi)實(shí)現(xiàn)外部接口
內(nèi)部類(lèi)還有一些更為有意思的結(jié)構(gòu),即:如果現(xiàn)在 定義了一個(gè)接口,那么可以在內(nèi)部利用類(lèi)實(shí)現(xiàn)該接口 ,在JDK1.8之后,接口中追加了static方法可以不受到實(shí)例化對(duì)象的控制,現(xiàn)在就可以利用此特性來(lái)完成功能。
接口內(nèi)部進(jìn)行接口實(shí)現(xiàn)
public interface IChannel {
public void send();
class ChannelImpl implements IChannel{
public void send(){
System.out.println("哈哈");
}
}
public static IChannel getInstance(){
return new ChannelImpl();
}
}
public class Test {
public static void main(String[] args) {
IChannel channel = IChannel.getInstance();
channel.send();
}
}
輸出的結(jié)果為“哈哈”
從上面可以看到,內(nèi)部類(lèi)是非常靈活的結(jié)構(gòu),只要你的語(yǔ)法滿足了,各種需求都可以幫你實(shí)現(xiàn)!
3. 總結(jié):
方法,類(lèi),抽象類(lèi),接口,代碼塊中都可以定義內(nèi)部結(jié)構(gòu)-------類(lèi),抽象類(lèi),接口。今天主要講了如何在內(nèi)部類(lèi)中使用內(nèi)部類(lèi)和接口中使用內(nèi)部類(lèi)。
-
程序
+關(guān)注
關(guān)注
115文章
3747瀏覽量
80665 -
代碼
+關(guān)注
關(guān)注
30文章
4697瀏覽量
68083
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論