在本教程中,您將借助示例學(xué)習(xí)Java中的嵌套類及其類型。
在Java中,您可以在另一個(gè)類中定義一個(gè)類。這樣的類稱為nested class(嵌套類)。例如,
class OuterClass { // ... class NestedClass { // ... } }
您可以使用Java創(chuàng)建兩種類型的嵌套類。
非靜態(tài)嵌套類(內(nèi)部類)
靜態(tài)嵌套類
相關(guān)閱讀:
首先讓我們看一下非靜態(tài)嵌套類。
非靜態(tài)嵌套類是另一個(gè)類中的一個(gè)類。它有權(quán)訪問封閉類(外部類)的成員。它通常被稱為inner class(內(nèi)部類)。
由于內(nèi)部類存在于外部類中,因此必須首先實(shí)例化外部類,以便實(shí)例化內(nèi)部類。
這是一個(gè)如何在Java中聲明內(nèi)部類的示例。
class CPU { double price; // 嵌套類 class Processor{ //嵌套類的成員 double cores; String manufacturer; double getCache(){ return 4.3; } } //嵌套受保護(hù)的類 protected class RAM{ //受保護(hù)的嵌套類的成員 double memory; String manufacturer; double getClockSpeed(){ return 5.5; } } } public class Main { public static void main(String[] args) { //創(chuàng)建外部類CPU的對(duì)象 CPU cpu = new CPU(); //使用外部類創(chuàng)建內(nèi)部類Processor的對(duì)象 CPU.Processor processor = cpu.new Processor(); //使用外部類CPU創(chuàng)建內(nèi)部類RAM的對(duì)象 CPU.RAM ram = cpu.new RAM(); System.out.println("Processor Cache = " + processor.getCache()); System.out.println("Ram Clock speed = " + ram.getClockSpeed()); } }
輸出:
Processor Cache = 4.3 Ram Clock speed = 5.5
在上面的程序中,有兩個(gè)嵌套類:Processor和RAM在外部類CPU內(nèi)部:。我們可以將內(nèi)部類聲明為受保護(hù)的。因此,我們已將RAM類聲明為受保護(hù)的。
在Main類里面
我們首先創(chuàng)建一個(gè)名為cpu的外部類CPU的實(shí)例。
然后,使用外部類的實(shí)例,創(chuàng)建內(nèi)部類的對(duì)象:
CPU.Processor processor = cpu.new Processor; CPU.RAM ram = cpu.new RAM();
注意:我們使用點(diǎn)(.)運(yùn)算符使用外部類創(chuàng)建內(nèi)部類的實(shí)例。
我們可以使用this關(guān)鍵字訪問外部類的成員。如果您想了解這個(gè)關(guān)鍵字,請(qǐng)?jiān)L問Java this關(guān)鍵字。
class Car { String carName; String carType; //使用構(gòu)造函數(shù)賦值 public Car(String name, String type) { this.carName = name; this.carType = type; } // private 方法 private String getCarName() { return this.carName; } //內(nèi)部類 class Engine { String engineType; void setEngine() { //訪問Car的carType屬性 if(Car.this.carType.equals("4WD")){ //調(diào)用Car的getCarName()方法 if(Car.this.getCarName().equals("Crysler")) { this.engineType = "Smaller"; } else { this.engineType = "Bigger"; } }else{ this.engineType = "Bigger"; } } String getEngineType(){ return this.engineType; } } } public class Main { public static void main(String[] args) { //創(chuàng)建外部類Car的對(duì)象 Car car1 = new Car("Mazda", "8WD"); //使用外部類創(chuàng)建內(nèi)部類的對(duì)象 Car.Engine engine = car1.new Engine(); engine.setEngine(); System.out.println("8WD發(fā)動(dòng)機(jī)類型= " + engine.getEngineType()); Car car2 = new Car("Crysler", "4WD"); Car.Engine c2engine = car2.new Engine(); c2engine.setEngine(); System.out.println("4WD發(fā)動(dòng)機(jī)類型 = " + c2engine.getEngineType()); } }
輸出:
8WD發(fā)動(dòng)機(jī)類型= Bigger 4WD發(fā)動(dòng)機(jī)類型 = Smaller
在上面的程序中,我們?cè)谕獠款怌ar中有一個(gè)名為Engine的內(nèi)部類。 在這里,請(qǐng)注意這行,
if(Car.this.carType.equals("4WD")) {...}
我們使用this關(guān)鍵字來訪問carType外部類的變量。您可能已經(jīng)注意到,使用Car.this.carType而不是使用this.carType。
這是因?yàn)槿绻覀儧]有提到外部類的名稱Car,那么this關(guān)鍵字將表示內(nèi)部類中的成員。
同樣,我們也從內(nèi)部類訪問外部類的方法。
if (Car.this.getCarName().equals("Crysler") {...}
需要注意的是,盡管getCarName()是一個(gè)private方法,但我們能夠從內(nèi)部類訪問它。
在Java中,我們還可以在另一個(gè)類中定義一個(gè)靜態(tài)(static)類。 這種類稱為靜態(tài)嵌套類(static nested class)。 靜態(tài)嵌套類不稱為靜態(tài)內(nèi)部類。
與內(nèi)部類不同,靜態(tài)嵌套類無法訪問外部類的成員變量。這是因?yàn)?strong>靜態(tài)嵌套類不需要您創(chuàng)建外部類的實(shí)例。
OuterClass.NestedClass obj = new OuterClass.NestedClass();
在這里,我們僅通過使用外部類的類名來創(chuàng)建靜態(tài)嵌套類的對(duì)象。因此,不能使用OuterClass.this引用外部類。
class MotherBoard { //靜態(tài)嵌套類 static class USB{ int usb2 = 2; int usb3 = 1; int getTotalPorts(){ return usb2 + usb3; } } } public class Main { public static void main(String[] args) { //創(chuàng)建靜態(tài)嵌套類的對(duì)象 //使用外部類的名稱 MotherBoard.USB usb = new MotherBoard.USB(); System.out.println("Total Ports = " + usb.getTotalPorts()); } }
輸出:
Total Ports = 3
在上面的程序中,我們?cè)陬怣otherBoard中創(chuàng)建了一個(gè)名為USB的靜態(tài)類。 注意這一行,
MotherBoard.USB usb = new MotherBoard.USB();
在這里,我們使用外部類的名稱創(chuàng)建一個(gè)USB對(duì)象。
現(xiàn)在,讓我們看看如果嘗試訪問外部類的成員會(huì)發(fā)生什么:
class MotherBoard { String model; public MotherBoard(String model) { this.model = model; } //靜態(tài)嵌套類 static class USB{ int usb2 = 2; int usb3 = 1; int getTotalPorts(){ //訪問外部類的變量model if(MotherBoard.this.model.equals("MSI")) { return 4; } else { return usb2 + usb3; } } } } public class Main { public static void main(String[] args) { //創(chuàng)建靜態(tài)嵌套類的對(duì)象 MotherBoard.USB usb = new MotherBoard.USB(); System.out.println("Total Ports = " + usb.getTotalPorts()); } }
當(dāng)我們嘗試運(yùn)行該程序時(shí),將出現(xiàn)錯(cuò)誤:
error: non-static variable this cannot be referenced from a static context
這是因?yàn)槲覀儧]有使用外部類的對(duì)象來創(chuàng)建內(nèi)部類的對(duì)象。 因此,沒有引用存儲(chǔ)在Motherboard.this中的外部類Motherboard。
Java將內(nèi)部類視為類的常規(guī)成員。它們就像在類中聲明的方法和變量一樣。
由于內(nèi)部類是外部類的成員,所以可以將任何訪問修飾符(如private、protected)應(yīng)用到內(nèi)部類,這在普通類中是不可能的。
由于嵌套類是其封閉的外部類的成員,因此您可以使用點(diǎn)(.)表示法訪問嵌套類及其成員。
使用嵌套的類將使您的代碼更具可讀性,并提供更好的封裝。
非靜態(tài)嵌套類(內(nèi)部類)可以訪問外部/封閉類的其他成員,即使它們被聲明為私有的也是如此。