成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

打好Java基礎(chǔ),從使用內(nèi)部類開始!

開發(fā) 后端
比起面向?qū)ο缶幊讨衅渌母拍顏?lái),接口和內(nèi)部類更深?yuàn)W復(fù)雜,比如 C++ 就沒(méi)有這些。將兩者結(jié)合起來(lái),可以解決 C++ 中用多重繼承所能解決的問(wèn)題,然后,多重繼承在 C++ 中被證明是相當(dāng)難以使用的,相比較而言,Java 的接口和內(nèi)部類就容易理解多了!

本文轉(zhuǎn)載自微信公眾號(hào)「小菜良記」,作者蔡不菜丶 。轉(zhuǎn)載本文請(qǐng)聯(lián)系小菜良記公眾號(hào)。

本文主要介紹 Java中內(nèi)部類的用法

今天又周五了呀,正在想明天周六有啥安排的時(shí)候,一聲驚訝聲打斷了我

小蔡小菜,你看看這組代碼,好靈活啊

聽到領(lǐng)桌小王的驚訝,我扭頭看了下他的屏幕,這不就是內(nèi)部類么。用的好當(dāng)然就靈活啦,只是我們平常沒(méi)怎么用。

內(nèi)部類用的好真的好靈活呀,我對(duì)這一塊還不是很熟悉,看來(lái)還得多學(xué)習(xí)學(xué)習(xí)!小菜,看你的樣子好像挺了解的,你能給我講講嗎?

看著小王如饑似渴的眼色,我不由有點(diǎn)心虛,內(nèi)心活動(dòng)也是極其復(fù)雜:我平時(shí)也沒(méi)咋用,只是有個(gè)大概的了解,講出來(lái)不就獻(xiàn)丑了,連忙聲道:

好說(shuō)好說(shuō),不過(guò)今天都周五了,也不差這一時(shí)半會(huì),咱們還是想想明天有啥活動(dòng),等下周來(lái)我再給你好好講講!

小王仿佛被我忽悠過(guò)去了,也沒(méi)看到我眼神中的慌亂,答應(yīng)了下來(lái)。

好在有驚無(wú)險(xiǎn),周末還能有啥安排,趕緊把內(nèi)部類安排上!

初識(shí)

比起面向?qū)ο缶幊讨衅渌母拍顏?lái),接口和內(nèi)部類更深?yuàn)W復(fù)雜,比如 C++ 就沒(méi)有這些。將兩者結(jié)合起來(lái),可以解決 C++ 中用多重繼承所能解決的問(wèn)題,然后,多重繼承在 C++ 中被證明是相當(dāng)難以使用的,相比較而言,Java 的接口和內(nèi)部類就容易理解多了!

一、內(nèi)部類如何創(chuàng)建

內(nèi)部類,顧名思義就是類中類,將類定義在外圍類里面:

  1. public class Animal { 
  2.  
  3.     class Monkey{ 
  4.         private String name = "monkey"
  5.  
  6.         public String getName() { 
  7.             return name
  8.         } 
  9.     } 
  10.  
  11.     class Pig { 
  12.         private String color; 
  13.  
  14.         Pig(String color) { 
  15.             this.color = color; 
  16.         } 
  17.  
  18.         String getColor() { 
  19.             return color; 
  20.         } 
  21.     } 
  22.  
  23.     public void getAnimal(String note) { 
  24.         Monkey monkey = new Monkey(); 
  25.         Pig pig = new Pig(note); 
  26.         System.out.println(pig.getColor()); 
  27.     } 
  28.  
  29.     public static void main(String[] args) { 
  30.         Animal animal = new Animal(); 
  31.         animal.getAnimal("pink"); 
  32.     } 
  33. /* OUTPIT: 
  34. pink 
  35. */ 

因?yàn)镸onkey和Pig兩個(gè)類是定義在 Animal 類中,因此使用起這兩個(gè)內(nèi)部類跟使用普通類沒(méi)什么區(qū)別。下面這組代碼相信小伙伴也不陌生:

  1. public class Animal { 
  2.  
  3.     class Monkey{ 
  4.     } 
  5.  
  6.     class Pig { 
  7.     } 
  8.  
  9.     public Monkey getMonkey() { 
  10.         return new Monkey(); 
  11.     } 
  12.  
  13.     public Pig getPig() { 
  14.         return new Pig(); 
  15.     } 
  16.  
  17.     public static void main(String[] args) { 
  18.         Animal animal = new Animal(); 
  19.         Animal.Monkey monkey = animal.getMonkey(); 
  20.         Animal.Pig pig = animal.getPig(); 
  21.     } 

通過(guò)定義方法,來(lái)返回執(zhí)行內(nèi)部類的引用。不知道細(xì)心的小伙伴有沒(méi)有注意到內(nèi)部類的引用有點(diǎn)奇怪:Animal.Monkey。這也是內(nèi)部類的區(qū)別之一,如果要在外部類的非靜態(tài)方法之外獲取某個(gè)內(nèi)部類的對(duì)象,需要「具體指明這個(gè)對(duì)象的類型」:OuterClassName.InnerClassName

二、內(nèi)外相連

內(nèi)部類存在于外部類里層,因此也具有一定特權(quán):內(nèi)部類可以訪問(wèn)外圍對(duì)象的所有成員,不需要任何特殊條件,此外,內(nèi)部類還擁有外部類的所有元素的訪問(wèn)權(quán)。

  1. public class OuterArray { 
  2.     private Integer[] ints; 
  3.     private int next = 0; 
  4.  
  5.     public OuterArray(int size) { 
  6.         ints = new Integer[size]; 
  7.     } 
  8.  
  9.     public void add(int x) { 
  10.         if (next < ints.length) { 
  11.             ints[next++] = x; 
  12.         } 
  13.     } 
  14.  
  15.     class InnerArray { 
  16.         private int i = 0; 
  17.  
  18.         public boolean end() { 
  19.             return i == ints.length; 
  20.         } 
  21.  
  22.         public int current() { 
  23.             return ints[i]; 
  24.         } 
  25.  
  26.         public void next() { 
  27.             if (i < ints.length) { 
  28.                 i++; 
  29.             } 
  30.         } 
  31.     } 
  32.  
  33.     public static void main(String[] args) { 
  34.         OuterArray outerArray = new OuterArray(10); 
  35.         for (int i = 0; i < 10; i++) { 
  36.             outerArray.add(i); 
  37.         } 
  38.         InnerArray innerArray = outerArray.new InnerArray(); 
  39.         while (!innerArray.end()) { 
  40.             System.out.print(innerArray.current()+" "); 
  41.             innerArray.next(); 
  42.         } 
  43.     } 

上組代碼中我們可以看到,InnerArray可以訪問(wèn)到OuterArray中的每一個(gè)屬性,就像自己擁有它們一樣,這帶來(lái)了很大的方便。

三、new 和 this

這兩個(gè)關(guān)鍵字我們肯定都不陌生了,我們平時(shí)用到最多的肯定就是new一個(gè)對(duì)象出來(lái)。

  1. public class OuterClass { 
  2.  
  3.     class InnerClass { 
  4.     } 
  5.  
  6.     public static void main(String[] args) { 
  7.         OuterClass outer = new OuterClass(); 
  8.     } 

當(dāng)我們需要OuterClass對(duì)象的時(shí)候,我們順手就來(lái)了個(gè)new OuterClass(),但是如果我們需要的是InnerClass對(duì)象,那么又該如何處理呢?答案便是:

  1. InnerClass inner = outer.new InnerClass(); 

可能覺(jué)得有點(diǎn)奇怪,為什么此處的new需要以O(shè)uterClass對(duì)象引用,這是因?yàn)閮?nèi)部類對(duì)象會(huì)暗暗地連接到創(chuàng)建它的外部類對(duì)象上,因此必須使用外部類的對(duì)象來(lái)創(chuàng)建內(nèi)部類對(duì)象。如果你創(chuàng)建的是「嵌套類」(靜態(tài)內(nèi)部類),那么它就不需要對(duì)外部類對(duì)象的引用。

this關(guān)鍵字是用來(lái)生成對(duì)外部類對(duì)象的引用,這樣產(chǎn)生的引用自動(dòng)具有正確的類型:

  1. public class OuterClass { 
  2.  
  3.     class InnerClass { 
  4.         public OuterClass getOuterClass() { 
  5.             return OuterClass.this; 
  6.         } 
  7.     } 
  8.  
  9.     public static void main(String[] args) { 
  10.         OuterClass outer = new OuterClass(); 
  11.         InnerClass inner = outer.new InnerClass(); 
  12.         OuterClass outerClass = inner.getOuterClass(); 
  13.     } 

四、局部?jī)?nèi)部類

我們上面看到的內(nèi)部類都是定義在外部類中,這也是內(nèi)部類的典型用處。但是,我們也可以在一個(gè)方法里面或者任意的作用域里面定義內(nèi)部類。這種也被稱為局部?jī)?nèi)部類:

  1. public class OuterClass { 
  2.  
  3.     public Animal getPig(String color) { 
  4.         class Pig extends Animal { 
  5.             @Override 
  6.             public void getAnimal(String color) { 
  7.                 super.getAnimal(color); 
  8.             } 
  9.         } 
  10.         return new Pig(); 
  11.     } 
  12.  
  13.     public static void main(String[] args) { 
  14.         OuterClass outerClass = new OuterClass(); 
  15.         Animal pink = outerClass.getPig("pink"); 
  16.     } 

Pig類是getPig()方法的一部分,而不是OuterClass的一部分,所以在getPig()之外不能訪問(wèn)Pig類。

五、匿名內(nèi)部類

在了解什么是匿名內(nèi)部類之前,我們先看一組代碼:

  1. public class OuterClass { 
  2.  
  3.     public Animal animal() { 
  4.         return new Animal(){ 
  5.             private String name = "monkey"
  6.             @Override 
  7.             public String toString() { 
  8.                 return "animal{" + 
  9.                         "name='" + name + '\'' + 
  10.                         '}'
  11.             } 
  12.         }; 
  13.     } 
  14.  
  15.     public static void main(String[] args) { 
  16.         OuterClass outerClass = new OuterClass(); 
  17.         System.out.println(outerClass.animal()); 
  18.     } 
  19. /* OUTPUT
  20. animal{name='monkey'
  21. */ 

animal()這個(gè)方法將返回值的生成與表示這個(gè)返回值的類定義結(jié)合在一起。而且這個(gè)類是匿名的,它沒(méi)有名字,正常形式應(yīng)該是這樣的:

  1. public class OuterClass { 
  2.  
  3.     class Monkey extends Animal { 
  4.         private String name = "monkey"
  5.  
  6.         @Override 
  7.         public String toString() { 
  8.             return "animal{" + 
  9.                     "name='" + name + '\'' + 
  10.                     '}'
  11.         } 
  12.     } 
  13.      
  14.     public Animal animal() { 
  15.         return new Monkey(); 
  16.     } 

匿名類再訪工廠:

  1. public interface Service { 
  2.     void method1(); 
  3. interface ServiceFactory{ 
  4.     Service getService(); 
  5.  
  6. class Implementation1 implements Service { 
  7.  
  8.     private Implementation1(){} 
  9.  
  10.     @Override 
  11.     public void method1() { 
  12.         System.out.println("Implementation1.method1()"); 
  13.     } 
  14.  
  15.     public static ServiceFactory factory = new ServiceFactory() { 
  16.         @Override 
  17.         public Service getService() { 
  18.             return new Implementation1(); 
  19.         } 
  20.     }; 
  21.  
  22. class Factories{ 
  23.     public static void main(String[] args) { 
  24.         ServiceFactory factory = Implementation1.factory; 
  25.         Service service = factory.getService(); 
  26.         service.method1(); 
  27.     } 

通過(guò)內(nèi)部類獲取外部類的實(shí)現(xiàn),這樣子Implementation1的構(gòu)造器都可以是private的,并且沒(méi)有任何必要去創(chuàng)建作為工廠的具體類,這樣所產(chǎn)生的語(yǔ)法也更具有實(shí)際意義,也可以運(yùn)用在單例模式中。

六、嵌套類

如果不需要內(nèi)部類對(duì)象與外圍類之間有聯(lián)系,就可以將內(nèi)部類聲明為static,這通常稱為嵌套類。普通的內(nèi)部類對(duì)象隱式地保存了一個(gè)引用,指向創(chuàng)建它的外圍類對(duì)象,然而,當(dāng)內(nèi)部類是static的時(shí)候,就意味著:

要?jiǎng)?chuàng)建嵌套類的對(duì)象,并不需要其外圍類的對(duì)象

不能從嵌套類的對(duì)象中訪問(wèn)非靜態(tài)的外圍類對(duì)象

  1. public class NestClass { 
  2.      
  3.     static class InnerNestClass{ 
  4.     } 
  5.  
  6.     public static InnerNestClass get() { 
  7.         return new InnerNestClass(); 
  8.     } 
  9.  
  10.     public static void main(String[] args) { 
  11.         InnerNestClass innerNestClass = get(); 
  12.     } 

在main()方法中沒(méi)有任何NestClass對(duì)象是必須的,而是使用選取static成員的普通語(yǔ)法來(lái)調(diào)用方法。

接口內(nèi)部類

正常情況下,不能在接口內(nèi)部放置任何代碼,但嵌套類可以作為接口的一部分。你放到接口中的任何類都自動(dòng)是public和static的。因?yàn)轭愂莝tatic的,只是將嵌套類置于接口的命名空間內(nèi),這并不違反接口的規(guī)則。你甚至可以在內(nèi)部類中實(shí)現(xiàn)其外部類的接口:

  1. public interface ClassInterface { 
  2.  
  3.     void test(); 
  4.  
  5.     class Test implements ClassInterface { 
  6.  
  7.         @Override 
  8.         public void test() { 
  9.             System.out.println("接口中的嵌套類"); 
  10.         } 
  11.  
  12.         public static void main(String[] args) { 
  13.             new Test().test(); 
  14.         } 
  15.     } 

如果你想要的創(chuàng)建某些公共代碼,使得它們可以被某個(gè)接口的所有不同實(shí)現(xiàn)所共用,那么使用接口內(nèi)部的嵌套類會(huì)顯得很方便,盡管在 Java 8 之后可以使用 default 來(lái)默認(rèn)實(shí)現(xiàn)接口方法。

七、繼承內(nèi)部類

內(nèi)部類作為一種類,被繼承當(dāng)然也是被允許的。但是因?yàn)閮?nèi)部類的構(gòu)造器必須連接到指向其外圍類對(duì)象的引用,所以在繼承內(nèi)部類的時(shí)候,那個(gè)指向外圍類對(duì)象的引用必須被初始化,而在導(dǎo)出類中不再存在可連接的默認(rèn)對(duì)象:

可以看到,通過(guò)這樣繼承是會(huì)報(bào)錯(cuò)的,解決方法便是:

  1. class ExtendClass { 
  2.     class Inner{} 
  3.  
  4. class WithInner extends ExtendClass.Inner { 
  5.     public WithInner(ExtendClass extendClass) { 
  6.         extendClass.super(); 
  7.     } 

因此我們需要記住,如果要繼承一個(gè)內(nèi)部類的時(shí)候,必須在構(gòu)造器內(nèi)使用外部類.super(),這樣才能提供了必要的引用,然后程序才能編譯通過(guò)。

八、覆蓋內(nèi)部類?

當(dāng)子類繼承父類時(shí),子類可以覆蓋父類的方法。那么問(wèn)題來(lái)了,內(nèi)部類能否被覆蓋?我們通過(guò)看一組代碼來(lái)找找答案:

  1. public class Flower { 
  2.  
  3.     class Bud{ 
  4.         public Bud(){ 
  5.             System.out.println("Flower.Bud"); 
  6.         } 
  7.     } 
  8.  
  9.     public Flower(){ 
  10.         System.out.println("new Flower()"); 
  11.         new Bud(); 
  12.         test(); 
  13.     } 
  14.  
  15.     public void test() { 
  16.         System.out.println("Flower.test()"); 
  17.     } 
  18.  
  19. class Flower2 extends Flower{ 
  20.  
  21.     class Bud{ 
  22.         public Bud(){ 
  23.             System.out.println("Flower2.Bud"); 
  24.         } 
  25.     } 
  26.     public void test() { 
  27.         System.out.println("Flower2.test()"); 
  28.     } 
  29.  
  30.     public static void main(String[] args) { 
  31.         new Flower2(); 
  32.     } 
  33. /* OUTPUT 
  34. new Flower() 
  35. Flower.Bud 
  36. Flower2.test() 
  37. */ 

從這個(gè)例子中我們可以看到,當(dāng)繼承了某個(gè)外圍類的時(shí)候,內(nèi)部類并沒(méi)有發(fā)生什么特別神奇的變化,這兩個(gè)內(nèi)部類是完全獨(dú)立的兩個(gè)實(shí)體,各自在自己的命名空間內(nèi)。

九、為什么要使用內(nèi)部類?

我們?cè)诨卮疬@個(gè)問(wèn)題之前先明白一件事情:

「每個(gè)內(nèi)部類都能獨(dú)立地繼承一個(gè)(接口的)實(shí)現(xiàn),所以無(wú)論外圍類是否已經(jīng)繼承了某個(gè)(接口的)實(shí)現(xiàn),對(duì)于內(nèi)部類都沒(méi)有影響」

這句話很清楚的說(shuō)明了內(nèi)部類的能力,如果沒(méi)有內(nèi)部類提供的、可以繼承多個(gè)具體的或抽象的類的能力,一些設(shè)計(jì)與編程問(wèn)題就很難解決,從這個(gè)角度看,內(nèi)部類使得多重繼承的解決方案變得完整。接口解決了部分問(wèn)題,為內(nèi)部類有效地實(shí)現(xiàn)了"多重繼承"。

呼~ 終于把內(nèi)部類復(fù)習(xí)的差不多了,乍看時(shí)間,今天都周末了呀!看來(lái)周末又沒(méi)安排計(jì)劃咯,不過(guò)這周過(guò)的還挺充實(shí)的,把基礎(chǔ)鞏固了一下,周一的時(shí)候還可以跟小王好好嘮嘮,想到這里,小菜不禁又陷入無(wú)限的幻想!

 

責(zé)任編輯:武曉燕 來(lái)源: 小菜良記
相關(guān)推薦

2011-03-29 14:11:15

內(nèi)部類

2020-01-15 11:14:21

Java算法排序

2020-12-14 10:23:23

Java內(nèi)部類外部類

2016-05-10 11:22:13

軟件定義IT基礎(chǔ)

2020-01-12 19:10:30

Java程序員數(shù)據(jù)

2009-07-29 09:18:49

Java內(nèi)部類

2010-04-06 09:16:08

CentOS系統(tǒng)

2009-06-11 13:08:29

Java內(nèi)部類Java編程思想

2023-03-06 07:53:36

JavaN種內(nèi)部類

2023-10-19 13:24:00

Java工具

2011-07-21 15:44:33

Java內(nèi)部類

2019-12-23 14:32:38

Java內(nèi)部類代碼

2020-04-17 10:26:27

IT成本領(lǐng)導(dǎo)者成本優(yōu)化

2012-04-17 11:21:50

Java

2015-12-08 09:05:41

Java內(nèi)部類

2021-02-08 08:45:18

Java內(nèi)部類Object類

2009-08-26 18:00:07

C#內(nèi)部類

2025-03-26 02:00:00

2024-06-11 11:16:21

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 亚洲高清在线观看 | 精品福利视频一区二区三区 | 欧美精品二区三区 | 日本三级黄视频 | 国产成人99久久亚洲综合精品 | 日韩成人影院 | 亚洲欧美激情国产综合久久久 | 精品毛片在线观看 | 国产av毛片 | 国产精品久久久久久影院8一贰佰 | 91在线观看 | 欧美午夜一区 | 一区二区三区精品在线 | 久久九 | 久草免费视 | 欧美大片一区二区 | 日韩中文一区二区 | 午夜不卡一区二区 | 伊人超碰在线 | 日韩毛片免费看 | 黄色一级片视频 | www.蜜桃av.com | 日本二区在线观看 | 欧美一区二区黄 | 日韩电影一区 | 亚洲一区二区三区视频 | 美女一区 | 成年人黄色一级毛片 | 亚洲激情一区二区三区 | 91精品入口蜜桃 | 日韩在线| 午夜羞羞 | 超碰97在线免费 | 99久久精品免费看国产免费软件 | 国产片侵犯亲女视频播放 | 夜夜爽99久久国产综合精品女不卡 | 国产精品二区三区在线观看 | 97在线观视频免费观看 | 一级免费毛片 | 亚洲综合在线视频 | 亚洲精彩视频在线观看 |