内部类详解
在一个类中定义的类叫做内部类。内部类分为四种:成员内部类,静态内部类,局部内部类,匿名内部类
1.成员内部类---在一个类中定义,类似于成员变量
/** * 成员内部类 * 内部类属于外部类的一个成员,所以内部类可以直接使用外部类的成员 * */ class Outer{ int num = 2; class Inner{ public void show(){ System.out.println(num); } } public void fun(){ Inner inner = new Inner(); inner.show(); } } public class Test { public static void main(String[] args) { Outer outer = new Outer(); outer.fun(); //直接创建内部类对象 Outer.Inner inner = new Outer().new Inner(); inner.show(); } }
运行结果:
2
2
成员变量num,成员函数fun,成员内部类Inner,都是Outer的成员,三者可以相互调用。
show()依附于Inner,Inner依附于Outer-----获取show(),要获取new Inner()---要获取new Inner(),要获取new Outer()
Outer.class与Inner.class的字节码文件的名称如下:
Outer.class----Outer$Inner.class
2.静态内部类---static修饰
1 //静态内部类 2 class Outer{ 3 static int num = 2; 4 static class Inner{ 5 public void show(){ 6 System.out.println(num); 7 } 8 } 9 public void fun(){ 10 Inner inner = new Inner(); 11 inner.show(); 12 } 13 } 14 15 public class Test { 16 17 public static void main(String[] args) { 18 19 Outer outer = new Outer(); 20 outer.fun(); 21 22 //直接创建内部类对象 23 Outer.Inner inner = new Outer.Inner(); 24 25 //这是错误的 26 //Outer.Inner inner = new Outer.new Inner(); 27 inner.show(); 28 } 29 }
运行结果:
2
2
成员变量num,成员函数fun,静态内部类Inner,都是Outer的成员。
show()依附于Inner,Inner依附于Outer-----获取show(),要获取new Inner()---要获取new Inner(),直接Outer点取 Outer.Inner
/** * 内部类中含有静态成员,那么内部类必须为static */ class Outer{ static int num = 2; static class Inner{ //内部类中含有静态成员,那么内部类必须为static public static void show(){ System.out.println(num); } } public void fun(){ Inner inner = new Inner(); inner.show(); } } public class Test { public static void main(String[] args) { Outer outer = new Outer(); outer.fun(); //直接创建内部类对象 Outer.Inner inner = new Outer.Inner(); inner.show(); } }
运行结果:
2
2
成员变量num,成员函数fun,静态内部类Inner,都是Outer的成员。
show()依附于Inner,Inner依附于Outer-----获取show(),要获取new Inner()---要获取new Inner(),直接Outer点取 Outer.Inner
/* * 内部类得到外部类对象中的成员 外部类名.this.成员 **/
1 class Outer{ 2 int num = 2; 3 class Inner{ 4 int num =3; 5 //内部类中含有静态成员,那么内部类必须为static 6 public void show(){ 7 int num =4; 8 System.out.println(num); 9 System.out.println(this.num); 10 System.out.println(Outer.this); 11 System.out.println(Outer.this.num); 12 //会出现错误 13 //System.out.println(Outer.num); 14 } 15 } 16 public void fun(){ 17 Inner inner = new Inner(); 18 inner.show(); 19 } 20 } 21 22 public class Test { 23 public static void main(String[] args) { 24 Outer outer = new Outer(); 25 outer.fun(); 26 } 27 }
运行结果:
4
3
langdon.Outer@40671416
2
System.out.println(Outer.this)输出的是Outer对象
3.局部内部类:在函数内部定义的类
/**
* 局部内部类
* 局部内部类使用了其所在函数的局部变量时,该局部变量必须是final的
*
*/
class Outer{
public void fun(){
final int num = 2;
class Inner{
public void show(){
//从内部类中访问本地变量num,num需要声明为final
System.out.println(num);
}
}
Inner inner = new Inner();
inner.show();
}
}
public class Test {
public static void main(String[] args) {
Outer outer = new Outer();
outer.fun();
}
}
运行结果:
2
class Outer{
Object obj;
public void fun(){
final int num = 2;
class Inner{
public void show(){
//从内部类中访问本地变量num,num需要声明为final
System.out.println("inner"+num);
}
public String toString() {
return "inner"+num;
}
}
obj = new Inner();//多态
}
public void function(){
System.out.println(obj.toString());
}
}
public class Test {
public static void main(String[] args) {
Outer outer = new Outer();
outer.fun();
outer.function();
}
}
运行结果:
inner2
4.匿名内部类:没有名字的内部类
(1)非匿名内部类----->匿名内部类(前提条件:存在父类)
1 /** 2 * 匿名内部类:没有名字的内部类 3 * 简化书写 4 * 前提条件:存在父类(TestMain)或父接口 5 * 6 */ 7 abstract class TestMain{ 8 public abstract void show(); 9 } 10 11 class Outer{ 12 13 class Inner extends TestMain{ 14 15 public void show(){ 16 17 System.out.println("show"); 18 19 } 20 21 22 public void eat() { 23 System.out.println("吃饭"); 24 } 25 26 27 } 28 29 public void fun(){ 30 Inner inner = new Inner(); 31 inner.show(); 32 inner.eat(); 33 } 34 35 36 } 37 38 39 public class Test { 40 41 public static void main(String[] args) { 42 //类 43 Outer outer = new Outer(); 44 outer.fun(); 45 46 } 47 48 }
1 /** 2 * 匿名内部类:没有名字的内部类 3 * 简化书写 4 * 前提条件:存在父类(TestMain)或父接口 5 * 6 */ 7 8 abstract class TestMain{ 9 public abstract void show(); 10 } 11 12 class Outer{ 13 class Inner extends TestMain{ 14 public void show(){ 15 System.out.println("show"); 16 } 17 18 public void eat() { 19 System.out.println("吃饭"); 20 } 21 22 } 23 24 public void fun(){ 25 //创建TestMain的子类对象 26 new TestMain(){ 27 public void show(){ 28 System.out.println("show"); 29 } 30 31 public void eat() { 32 System.out.println("吃饭"); 33 } 34 }.show(); 35 36 new TestMain(){ 37 public void show(){ 38 System.out.println("show"); 39 } 40 41 public void eat() { 42 System.out.println("吃饭"); 43 } 44 }.eat(); 45 46 } 47 48 } 49 50 public class Test { 51 public static void main(String[] args) { 52 //类 53 Outer outer = new Outer(); 54 outer.fun(); 55 } 56 }
运行结果:
show
吃饭
(2)匿名内部类(父类类型的引用指向了子类对象)
abstract class TestMain{ public abstract void show(); } class Outer{ class Inner extends TestMain{ public void show(){ System.out.println("show"); } public void eat() { System.out.println("吃饭"); } } public void fun(){ //父类类型的引用指向了子类对象,只能调用show() TestMain testMain = new TestMain(){ public void show(){ System.out.println("show"); } public void eat() { System.out.println("吃饭"); } }; testMain.show(); System.out.println(new Object(){ int age = 23; String name = "11"; public String toString(){ return name+","+age; } }); } } public class Test { public static void main(String[] args) { //类 Outer outer = new Outer(); outer.fun(); } }
运行结果:
show
11,23
(3)匿名内部类(前提条件:存在父接口)
interface inter{ public abstract void sleep(); } class Test1 implements inter{ public void sleep(){ System.out.println("睡觉"); } } public class Test { public static void main(String[] args) { //接口 Test1 t = new Test1(); ff(t); //使用匿名内部类调用函数ff ff(new inter(){ public void sleep(){ System.out.println("睡觉"); } public void learn(){ System.out.println("学习"); } }); } public static void ff(inter in){//inter in = new Test1() in.sleep(); } }
运行结果:
睡觉
睡觉