17.内部類
将一個類定義在另一個類的裡面,對裡面那個類就稱為内部類(内置類,嵌套類)。
通路特點:
内部類可以直接通路外部類中的成員,包括私有成員。
而外部類要通路内部類中的成員必須要建立内部類的對象。
18.内部類的位置
1.内部類定義在成員位置上
可以被private static成員修飾符修飾。
被static修飾的内部類隻能通路外部類中的靜态成員。
2.内部類定義在局部位置上
也可以直接通路外部類中的成員。
同時可以通路所在局部中的局部變量,但必須是被final修飾的。
19.匿名内部類
就是内部類的簡化寫法。
前提:
内部類可以繼承或實作一個外部類或者接口。
格式為:
new 外部類名或者接口名(){覆寫類或者接口中的代碼,(也可以自定義内容。)}
簡單了解:
就是建立一個帶内容的外部類或者接口的子類匿名對象。
class Outer{
private int num = 3;
static int num2 = 7;
//内部類:定義在成員位置上,它就相當于外部類的成員一樣,可以被成員修飾符所修飾。
public class Inner{
void show(){
System.out.println("show num="+num);
}
}
void method(){
//外部類要通路内部類中的成員,必須要建立内部類中的對象
Inner in = new Inner();
in.show();
}
static class Inner2{//被static修飾的内部類隻能通路外部類中的靜态成員
void show2(){
System.out.println("show2 num2="+num2);
}
}
static class Inner3 {
//當内部類中定義了靜态成員,該内部類必須被靜态修飾
static void show3(){
System.out.println("show3 num2="+num2);
}
}
}
class InnerDemo{
public static void main(String[] args) {
/*
直接通路内部類成員的方式。
*/
//1,對非靜态的内部類中的非靜态成員通路。
Outer.Inner in = new Outer().new Inner();
in.show();
//2,通路靜态内部類中的非靜态成員。
Outer.Inner2 in = new Outer.Inner2();
in.show2();
//3,通路靜态内部類中的靜态成員。
Outer.Inner3.show3();
//外部類通路外部類的方法,該方法中有内部類對象通路的方法
Outer out = new Outer();
out.method();
}
}
内部類直接通路外部類成員的原因
非靜态的内部類之是以能直接通路外部類成員的原因是:它持有了一個外部類對象的引用。
class Outer{
private int num = 2;
class Inner{
private int num = 3;
void show(){
int num = 4;
System.out.println("num="+num); //結果是4
System.out.println("num="+this.num); //結果是3
System.out.println("num="+Outer.this.num); //結果是2
}
}
void method(){
new Inner().show();
}
}
class Outer{
private int num = 3;
void method(){
final int x = 7; //内部類定義在局部中,隻能通路被final修飾的局部變量。
//不被final修飾的局部變量生命周期随着方法的釋放而釋放。
class Inner{//定義在局部的内部類。
void show(){
System.out.println("x="+x);
//System.out.println("num="+num);
}
}
new Inner().show();
}
}
class Outer2{
private int num = 4;
Object obj ;
public void method(){
final int x = 4;
class Inner{
public String toString(){
return "hahah"+x;
}
}
this.obj = new Inner();
}
}
class InnerDemo3 {
public static void main(String[] args) {
//new Outer().method();
Outer2 out = new Outer2();
out.method();
System.out.println(out.obj.toString());
}
}
/*
匿名内部類的形式。
其實就是對内部類進行簡化書寫。
必須有前提:
内部類必須繼承或者實作類或接口。
格式:
new 父類名或者接口名(){定義内部類的内容;}
匿名内部類其實就是一個子類匿名對象。
*/
abstract class AbsDemo{
abstract void function();
}
class Outer{
int num = 4;
/*
class Inner extends AbsDemo{
void function(){
System.out.println("num="+num);
}
}
*/
void method(){
//new Inner().function();
new AbsDemo() { //建立了子類的對象并且調用了子類的方法。
//對内部類的描述。
void function(){
System.out.println("num===="+num);
}
}.function(); //枚紅色的部分是綠色部分的簡寫, new X(){}是建立X子類對象
}
}
class NoNameInnerDemo {
public static void main(String[] args) {
Outer out = new Outer();
out.method();
}
}