1 /** 2 * 1.内部类可以直接访问外部类的成员,包括私有 3 * 2.外部类要访问内部类的成员必须创建对象 4 * @author jjz 5 * 6 */ 7 class outer1 { 8 private int num = 10; 9 class inner{ 10 public void show(){ 11 System.out.println(num); 12 } 13 } 14 15 public void show1(){ 16 //先创建内部类的对象 17 inner i = new inner(); 18 i.show(); 19 } 20 21 } 22 23 public class outer { 24 public static void main(String[] args) { 25 outer1 o = new outer1(); 26 o.show1(); 27 } 28 }
1 /** 2 * 成员内部类 3 */ 4 class Outer1 { 5 private static final int num =100; 6 class Inner{ 7 public void show(){ 8 System.out.println(num); 9 } 10 } 11 } 12 13 public class outer { 14 public static void main(String[] args) { 15 //成员内部类的访问格式:外部类名.内部类名 对象名 = new 外部类名().new 内部类名() 16 Outer1.Inner oi = new Outer1().new Inner(); 17 oi.show(); 18 } 19 }
成员内部类的修饰符:
private 为了保证数据的安全性
static 为了方便访问数据
注意:静态内部类访问的外部类数据必须用静态修饰。
案例:我有一个人(人有身体,身体内有心脏。)
1 class Body { 2 private class Heart { 3 public void operator() { 4 System.out.println("心脏搭桥"); 5 } 6 } 7 8 //加了private修饰之后就不能直接访问了,所以通过method访问 9 public void method() { 10 if(如果你是外科医生) { 11 Heart h = new Heart(); 12 h.operator(); 13 } 14 } 15 } 16 17 class test{ 18 public static void main (String []args){ 19 Body.Heart bh = new Body().new Heart(); 20 bh.operator();//加了private修饰之后就不能直接访问了 21 22 //调用method方法访问 23 Body b = new Body(); 24 b.method(); 25 } 26 }
static修饰内部类:
1 class Outer { 2 private int num = 10; 3 private static int num2 = 100; 4 5 //内部类用静态修饰是因为内部类可以看出是外部类的成员 6 public static class Inner { 7 public void show() { 8 //System.out.println(num); 9 System.out.println(num2); 10 } 11 12 public static void show2() { 13 //System.out.println(num); 14 System.out.println(num2); 15 } 16 } 17 } 18 19 class InnerClassDemo4 { 20 public static void main(String[] args) { 21 //使用内部类 22 // 限定的新静态类 23 //Outer.Inner oi = new Outer().new Inner(); 24 //oi.show(); 25 //oi.show2(); 26 27 //成员内部类被静态修饰后的访问方式是: 28 //格式:外部类名.内部类名 对象名 = new 外部类名.内部类名(); 29 Outer.Inner oi = new Outer.Inner(); 30 oi.show(); 31 oi.show2(); 32 33 //show2()的另一种调用方式 34 Outer.Inner.show2(); 35 } 36 }
1 /* 2 面试题: 3 要求请填空分别输出30,20,10。 4 5 注意: 6 1:内部类和外部类没有继承关系。 7 2:通过外部类名限定this对象 8 Outer.this 9 */ 10 class Outer { 11 public int num = 10; 12 class Inner { 13 public int num = 20; 14 public void show() { 15 int num = 30; 16 System.out.println();num 17 System.out.println();this.num 18 //System.out.println();new Outer().num 19 System.out.println();Outer.this.num 20 } 21 } 22 } 23 class InnerClassTest { 24 public static void main(String[] args) { 25 Outer.Inner oi = new Outer().new Inner(); 26 oi.show(); 27 } 28 }
局部内部类
A:可以直接访问外部类的成员
B:在局部位置,可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
面试题:
局部内部类访问局部变量的注意事项?
A:局部内部类访问局部变量必须用final修饰
B:为什么呢?
局部变量是随着方法的调用而调用,随着调用完毕而消失。
而堆内存的内容并不会立即消失。所以,我们加final修饰。
加入final修饰后,这个变量就成了常量。既然是常量。你消失了。
我在内存中存储的是数据20,所以,我还是有数据在使用。
1 class Outer { 2 private int num = 10; 3 4 public void method() { 5 //int num2 = 20; 6 //final int num2 = 20; 7 class Inner { 8 public void show() { 9 System.out.println(num); 10 //从内部类中访问本地变量num2; 需要被声明为最终类型 11 System.out.println(num2);//20 12 } 13 } 14 15 //System.out.println(num2); 16 17 Inner i = new Inner(); 18 i.show(); 19 } 20 } 21 22 class InnerClassDemo5 { 23 public static void main(String[] args) { 24 Outer o = new Outer(); 25 o.method(); 26 } 27 }
匿名内部类
1 /* 2 匿名内部类 3 就是内部类的简化写法。 4 5 前提:存在一个类或者接口 6 这里的类可以是具体类也可以是抽象类。 7 8 格式: 9 new 类名或者接口名(){ 10 重写方法; 11 } 12 13 本质是什么呢? 14 是一个继承了该类或者实现了该接口的子类匿名对象。 15 */ 16 interface Inter { 17 public abstract void show(); 18 public abstract void show2(); 19 } 20 21 class Outer { 22 public void method() { 23 //一个方法的时候 24 /* 25 new Inter() { 26 public void show() { 27 System.out.println("show"); 28 } 29 }.show(); 30 */ 31 32 //二个方法的时候 33 /* 34 new Inter() { 35 public void show() { 36 System.out.println("show"); 37 } 38 39 public void show2() { 40 System.out.println("show2"); 41 } 42 }.show(); 43 44 new Inter() { 45 public void show() { 46 System.out.println("show"); 47 } 48 49 public void show2() { 50 System.out.println("show2"); 51 } 52 }.show2(); 53 */ 54 55 //如果我是很多个方法,就很麻烦了 56 //那么,我们有没有改进的方案呢? 57 Inter i = new Inter() { //多态 58 public void show() { 59 System.out.println("show"); 60 } 61 62 public void show2() { 63 System.out.println("show2"); 64 } 65 }; 66 67 i.show(); 68 i.show2(); 69 } 70 } 71 72 class InnerClassDemo6 { 73 public static void main(String[] args) { 74 Outer o = new Outer(); 75 o.method(); 76 } 77 }
1 interface Person1{ 2 public abstract void study(); 3 } 4 5 //class student implements Person1{ 6 // 7 // @Override 8 // public void study() { 9 // System.out.println("好好学习 天天向上"); 10 // } 11 // 12 //} 13 14 class personDemo{ 15 public void show(Person1 p){ 16 p.study(); 17 } 18 } 19 20 public class outer { 21 public static void main(String[] args) { 22 personDemo pd = new personDemo(); 23 // Person1 p = new student(); 24 // pd.show(p); 25 //匿名内部类的本质是接口的实现类或者父类的子类的对象 26 pd.show(new Person1(){ 27 28 @Override 29 public void study() { 30 System.out.println("jjz 好好学习 天天向上"); 31 32 } 33 34 }); 35 } 36 }
1 /* 2 匿名内部类面试题: 3 按照要求,补齐代码 4 interface Inter { void show(); } 5 class Outer { //补齐代码 } 6 class OuterDemo { 7 public static void main(String[] args) { 8 Outer.method().show(); 9 } 10 } 11 要求在控制台输出”HelloWorld” 12 */ 13 interface Inter { 14 void show(); 15 //public abstract 16 } 17 18 class Outer { 19 //补齐代码 20 public static Inter method() { 21 //子类对象 -- 子类匿名对象 22 return new Inter() { 23 public void show() { 24 System.out.println("HelloWorld"); 25 } 26 }; 27 } 28 } 29 30 class OuterDemo { 31 public static void main(String[] args) { 32 Outer.method().show(); 33 /* 34 1:Outer.method()可以看出method()应该是Outer中的一个静态方法。 35 2:Outer.method().show()可以看出method()方法的返回值是一个对象。 36 又由于接口Inter中有一个show()方法,所以我认为method()方法的返回值类型是一个接口。 37 */ 38 } 39 }