内部类:一个类定义在另一个类的内部,那么该类就成为内部类。
内部类的class文件名:外部类$内部类。这样命名的好处是便于区分class文件是属于哪个外部类。
内部类的种类:
1、成员内部类
2、局部内部类
3、匿名内部类。
成员内部类:内部类的定义位置在外部类的成员位置。
成员内部类的应用场景:
在描述A事物的时候,发现描述的A事物内部还存在另一个比较复杂的事物B时候,而且这个比较复杂事物B还需要访问A事物的属性等数据,这个时候就可以使用内部类描述B事物。
成员内部类的访问方式:
方式一:在外部类提供一个方法创建内部类的对象进行访问。
方式2二:在其他类直接创建内部类的对象。 格式:外部类.内部类 变量名 = new 外部类().new 内部类();
注意: 如果是一个静态内部类,那么在其他类创建 的格式:
外部类.内部类 变量名 = new 外部类.内部类();
内部类要注意的细节:
1. 如果外部类与内部类存在同名的成员变量时,在内部类中默认情况下是访问内部类的成员变量。可以通过"外部类.this.成员变量名" 指定访问外部类的 成员。
2. 私有的成员内部类只能在外部类提供一个方法创建内部类的对象进行访问,不能在其他类创建对象了。
3. 成员内部类一旦出现了静态的成员,那么该类也必须 使用static修饰。
局部内部类:内部类的定义位置在外部类的方法中。
局部内部类要注意的细节:
如果局部内部类访问了一个局部变量,那么该局部变量必须使用final来修饰。但是经过测试好像不存在这个破规矩了呢。
匿名内部类:没有类名的类。
匿名内部类的好处:简化书写。好像带有匿名两个字的东东都有简化书写的作用呢,比如:匿名对象。
匿名内部类的使用前提:必须存在继承和实现关系。
匿名内部类一般是用于实参。
示例代码如下:
1 //继承关系 2 abstract class Animal 3 { 4 public abstract void run(); 5 } 6 7 //实现关系 8 interface Dao 9 { 10 public void add(); 11 } 12 13 class Outer 14 { 15 String name = "外部类"; 16 int x = 10; 17 class Inner 18 { 19 String name = "内部类"; 20 public void print(){ 21 //内部类可以直接访问外部类的所有成员。 22 System.out.println("外部类名字:"+Outer.this.name+" 内部类名字:"+name+" 外部类的变量x:"+x); 23 } 24 } 25 //在外部类中提供一个方法创建内部类并进行访问 26 public void instanceInner(){ 27 Inner inner = new Inner(); 28 inner.print(); 29 } 30 31 //成员内部类一旦出现了静态的成员,那么该类也必须 使用static修饰。 32 static class StaticInner 33 { 34 static String name = "静态内部类"; 35 public void print(){ 36 System.out.println("内部类的名字:"+name); 37 } 38 } 39 40 //局部内部类 41 public void testInner(){ 42 final int y = 100; 43 class LocalInner 44 { 45 public void print(){ 46 System.out.println("局部内部类的y值:"+y); 47 } 48 } 49 LocalInner localInner = new LocalInner(); 50 localInner.print(); 51 } 52 53 //匿名内部类 54 public void testanonymous(){ 55 //继承关系 56 new Animal(){ 57 public void run(){ 58 System.out.print("具体的动物跑起来了"); 59 } 60 }.run(); 61 //实现关系 62 new Dao(){ 63 public void add(){ 64 System.out.println("进行加操作"); 65 } 66 }; 67 } 68 } 69 70 class Demo 71 { 72 public static void main(String[] args) 73 { 74 75 Outer outer = new Outer(); 76 //outer.instanceInner(); 77 //局部内部类只能通过外部类方法进行访问 78 //outer.testInner(); 79 //outer.testanonymous(); 80 test(new Dao(){ 81 public void add(){ 82 System.out.println("进行了加法"); 83 } 84 }); 85 /* 86 //在其他类直接创建内部类的对象 87 Outer.Inner inner = new Outer().new Inner(); 88 inner.print(); 89 */ 90 /* 91 //静态成员内部类访问方式 92 Outer.StaticInner sInner = new Outer.StaticInner(); 93 sInner.print(); 94 */ 95 } 96 97 //匿名类作为实参来使用 98 public static void test(Dao d){ 99 d.add(); 100 } 101 }