java中的内部类
本文主要讲述java中的内部类
老韩介绍
- 局部内部类:
局部类示例代码如下:
1 public class LocalInnerClass { 2 public static void main(String[] args) { 3 Outer02 outer02 = new Outer02(); 4 outer02.OuterWork(); 5 System.out.println("LocalInnerClass中的Outer对象: "+outer02); 6 } 7 8 } 9 class Outer02{ 10 // 1.可以直接访问外部类的所有成员,包括私有的 11 private int age = 10; 12 13 private void happy(){ 14 System.out.println("Outer的private void happy()"); 15 } 16 // 3.作用域,只能在定义内部类的方法体或者代码块中。 17 public void OuterWork(){ 18 // 2.不能添加访问修饰符,能添加final关键字 19 final class Inner02 { 20 private int age = 11; 21 public void InnerWork(){ 22 // 7.外部类和内部类的成员变量名称相同,默认就近原则,如果想访问外部类的成员,可以用外部类名.this.外部类成员名 23 System.out.println("Inner02的age: "+age+" Outer02的age: "+Outer02.this.age); 24 // 验证outer对象与Outer02.this是否是同一个对象 25 System.out.println("Outer调用OuterWork()的对象: " + Outer02.this); 26 // 4.局部内部类直接访问外部类的属性和方法 27 happy(); 28 } 29 } 30 // 5.外部类访问内部类属性,方法,需要创建内部类对象。 31 Inner02 inner02 = new Inner02(); 32 inner02.InnerWork(); 33 } 34 }
运行结果如下:
不难看出,Outer02.this与outer对象是同一个对象,因此可以调用Outer的age属性。
- 匿名内部类
(1)基于接口的匿名内部类的使用,示例代码如下:
1 public class AnonymousInnerClass { 2 public static void main(String[] args) { 3 // new Tiger().cry(); 4 new Outer03().method(); 5 // new Outer03$1(); 6 } 7 } 8 class Outer03 { 9 private int n1 = 10; 10 public void method(){ 11 12 // 接口的多态 13 // tiger的编译类型是A,运行类型是匿名内部类 14 /* 15 // 匿名内部类的类名是系统分配的 16 class Outer03$1 implements A { 17 @Override 18 public void cry() { 19 System.out.println("老虎叫唤"); 20 } 21 } 22 //类创建完成后,立马创建该类的对象,将对象的地址赋给tiger. 23 A tiger = new Outer03$1(); 24 */ 25 A tiger = new A(){ 26 @Override 27 public void cry() { 28 System.out.println("老虎叫唤"); 29 } 30 }; 31 System.out.println("tiger的运行类型: "+tiger.getClass()); 32 tiger.cry(); 33 34 } 35 } 36 37 interface A { 38 public void cry(); 39 } 40 41 // 传统实现接口的方法 42 //class Tiger implements A{ 43 // @Override 44 // public void cry() { 45 // System.out.println("老虎叫唤"); 46 // } 47 //}
运行结果如下:
(2)基于类的匿名内部类的使用,示例代码如下:
1 public class AnonymousInnerClass { 2 public static void main(String[] args) { 3 // new Tiger().cry(); 4 new Outer03().method(); 5 // new Outer03$1(); 6 } 7 } 8 class Outer03 { 9 private int n1 = 10; 10 public void method(){ 11 12 // 不加大括号,表示对象 13 Father jack = new Father("jack"); 14 // 基于类的匿名内部类 15 // tom的编译类型是Father,运行类型是Outer03$2 16 /* 17 class Outer03$2 extends Father{ 18 @Override 19 public void test() { 20 System.out.println("类的匿名内部类的test()"); 21 } 22 } 23 Father tom = new Outer03$2(); 24 */ 25 Father tom = new Father("tom"){ 26 @Override 27 public void test() { 28 System.out.println("类的匿名内部类的test()"); 29 } 30 }; 31 tom.test();// 动态绑定机制 32 System.out.println("tom的运行类型: "+tom.getClass()); 33 34 } 35 } 36 37 class Father { 38 public Father(String name){ 39 40 } 41 42 public void test(){ 43 System.out.println("Father的test()"); 44 45 } 46 }
运行结果如下:
(3)基于抽象类的匿名内部类,示例代码如下:
1 public class AnonymousInnerClass { 2 public static void main(String[] args) { 3 // new Tiger().cry(); 4 new Outer03().method(); 5 // new Outer03$1(); 6 } 7 } 8 class Outer03 { 9 private int n1 = 10; 10 public void method(){ 11 12 // 基于抽象类的匿名内部类 13 /* 14 class Outer03$3 extends Animal{ 15 @Override 16 public void eat() { 17 System.out.println("抽象类的匿名内部类的eat()"); 18 } 19 } 20 Animal animal = new Outer03$3(); 21 */ 22 Animal animal = new Animal(){ 23 @Override 24 public void eat() { 25 System.out.println("抽象类的匿名内部类的eat()"); 26 } 27 }; 28 animal.eat(); 29 System.out.println("animal的运行类型: "+animal.getClass()); 30 } 31 } 32 33 abstract class Animal { 34 // 抽象类中的抽象方法需要用abstract指明 35 public abstract void eat(); 36 }
运行结果如下:
综合示例代码【考察动态绑定,匿名内部类】
1 public class AnonymousInnerClassDetail02 { 2 public static void main(String[] args) { 3 Person p = new Person(); 4 p.work(); 5 System.out.println("调用work的Person类: "+p); 6 } 7 8 } 9 class Dog { 10 // 动态绑定机制 11 private int n1 = setN1(); 12 public void walk(String name){ 13 System.out.println(name+"狗在跑"); 14 } 15 16 // 返回n1的值 17 public int getN1() { 18 return n1; 19 } 20 21 // 设置n1的值,验证方法的动态绑定机制 22 public int setN1() { 23 return 11; 24 } 25 26 // 验证方法的动态绑定机制 27 public void say(){ 28 System.out.println("the dog is very happy"); 29 } 30 } 31 class Person { 32 private int n1 = 10; 33 34 public void work(){ 35 // Person的匿名内部类的n1只能作用于该类的内部,无法在外部访问。 36 /* 37 class Person$1 extends Dog{ 38 private int n1 = 12; 39 @Override 40 public void walk(String name) { 41 super.walk(name); 42 } 43 } 44 Dog dog = new Person$1(); 45 dog.getN1(); 46 */ 47 // dog的编译类型是Dog,运行类型是匿名内部类Person$1 48 // 调用方法,有动态绑定机制,属性的话,就近原则。 49 Dog dog = new Dog(){ 50 private int n1 = 12; 51 @Override 52 public void walk(String name) { 53 super.walk(name); 54 // 访问外部类的成员变量,外部类名.this.属性名 55 System.out.println("Person的年龄是: "+ Person.this.n1); 56 System.out.println("调用walk的Person类: "+Person.this); 57 } 58 59 @Override 60 public void say() { 61 System.out.println("the Person is very happy"); 62 } 63 64 @Override 65 public int setN1() { 66 return 9; 67 } 68 69 // @Override 70 // public int getN1() { 71 // return n1; 72 // } 73 }; 74 dog.walk("大白"); 75 dog.say(); // 动态绑定机制 76 System.out.println("匿名内部类中的n1是: "+ dog.getN1()); 77 } 78 }
请自行验证输出结果。
- 成员内部类
成员内部类,示例代码如下:
1 public class MemberInnerClass { 2 public static void main(String[] args) { 3 Person tom = new Person("Tom", 18); 4 /** 5 * 非外部类使用成员内部类的对象,方式: 6 * 1.外部类对象.new 内部类构造器(); 7 * 2.外部类返回内部类对象的方法 8 */ 9 Person.Dog dog = tom.new Dog("大h", 20); 10 tom.walk(dog); 11 12 } 13 } 14 15 class Person { 16 private String name; 17 private int age; 18 19 public Person(String name, int age) { 20 this.name = name; 21 this.age = age; 22 } 23 24 public class Dog { 25 private String name = "大白"; 26 private int age = 5; 27 28 public Dog(String name, int age) { 29 this.name = name; 30 this.age = age; 31 } 32 33 public void run(){ 34 System.out.println(name+"狗,在跑,它的主人是: "+Person.this.name); 35 } 36 } 37 38 public void walk(Dog dog){ 39 System.out.println("主人: "+name+"在遛狗,狗的名字: "+dog.name); 40 dog.run(); 41 } 42 43 public Dog dog(){ 44 return new Dog("大b",5); 45 } 46 }
运行结果如下:
- 静态内部类
静态内部类示例代码如下:
public class StaticInnerClass { public static void main(String[] args) { Outer outer = new Outer(); outer.createInner(); /** * 非外部类使用静态内部类对象 * 方式 1:new 外部类.静态内部类的构造器 * 方式 2:外部类.返回静态内部类对象的普通方法 * 方式 3:外部类,返回静态内部类对象的静态方法 */ Outer.Inner inner1 = new Outer.Inner(); inner1.showOuter(); Outer.Inner inner2 = outer.getInner(); inner2.showOuter(); Outer.Inner inner3 = Outer.getInner_(); inner3.showOuter(); } } class Outer { private String name; private static int age = 20; private static void hello(){ System.out.println("Outer的hello()"); } // 静态内部类,只能访问父类的所有静态成员 static class Inner { private int age = 10; public void showOuter(){ System.out.println(Outer.age); hello(); } } public void createInner(){ Inner inner = new Inner(); inner.showOuter(); } // 普通方法,既能访问非静态成员,又能访问静态成员 public Inner getInner(){ Inner inner = new Inner(); return inner; } // 静态方法只能访问静态成员 public static Inner getInner_(){ Inner inner = new Inner(); return inner; } }