内部类
概念
内部类
内部类访问规则
1.内部类可以直接访问外部类中的成员,包括私有[例1]
之所以可以直接访问外部类成员,是因为内部类中持有了一个外部类的引用,格式是 外部类名.this[例3]
2.外部类要访问内部类,必须建立内部类对象[两种写法][例2]
第二种写法格式
当内部类定义在外部类成员位置上,而且非私有,可以在外部其他类中,直接创建内部类对象
外部类名.内部类名 变量名 =外部类对象.内部类对象
Outer. Inner in=new Outer().new Inner();
3.当内部类在成员位置,就可以被外部类修饰符所修饰
比如:private 将内部类在外部类中进行封装
4.静态内部类(static)
当内部类被static修饰后,内部类就具备了static特性,只能直接访问外部类中的static成员,也就是说出现了访问局限
误区
在外部其他类中,如何访问static内部类中的非static成员[例4]
外部类对象.内部类名().内部类非staic方法名()
new InnerDemo.ClassDemo().Demo();
在外部其他类中,如何访问static内部类中的static成员[例5]
外部类名.内部类名().内部类static方法();
InnerDemo.ClassDemo.Demo();
注意
当内部类中定义了静态成员,该内部类必须是静态的[例6]
当外部类中的静态方法访问内部类时,内部类必须是静态的[例7]
什么时候使用内部类?
当描述事物时,事物的内部还有事物,该事物用内部类来描述,因为内部事物在使用外部事物的内容
5.内部类定义在局部时[定义在外部类的方法中]
注意:内部类可以定义在外部类的任意位置,分为成员位置和局部位置,所以局部不单单指定义在方法中
(1)可以直接访问外部类的成员,因为还持有外部类的引用,但是不可以访问它所在的局部中的变量,只能访问被final修饰的局部中的变量[常量][例8]
典型特殊案例[例9]
匿名内部类
1.匿名内部类其实就是内部类的简写格式[例10]
2.定义匿名内部类的前提[例10]
内部类必须是继承一个类或者实现接口
3.匿名内部类的格式[例10]
new 父类或者接口() {定义子类的内容}
4.其实匿名内部类就是一个匿名子类对象,而且这个对象有点"胖",可以理解为没有名字带内容的对象[例10]
匿名内部类一次只能调用一个方法[例11]
5.匿名内部类中定义的房啊最好不要超过3个[不包括3个]
什么时候使用匿名内部类?
一个类继承一个接口,并且这个接口只有不到3个方法
示例代码
例1
1 import java.lang.reflect.Method; 2 3 import com.preview.seven.InnerDemo.ClassDemo; 4 5 public class InnerClass { 6 public static void main(String[] args) { 7 8 } 9 } 10 11 class InnerDemo { 12 private int num = 3; 13 14 class ClassDemo { 15 public void Demo() { 16 System.out.println("我是内部类的方法" + " " + num); //可以直接父类中的num,不会报错 17 } 18 } 19 20 public void inner2() { 21 System.out.println("我是外部类的方法"); 22 } 23 }
例2
第一种写法
1 import java.lang.reflect.Method; 2 3 import com.preview.seven.InnerDemo.ClassDemo; 4 5 public class InnerClass { 6 public static void main(String[] args) { 7 InnerDemo innerDemo=new InnerDemo(); 8 innerDemo.inner2(); 9 } 10 } 11 12 class InnerDemo { 13 private int num = 3; 14 15 class ClassDemo { 16 public void Demo() { 17 System.out.println("我是内部类的方法" + " " + num); //我是内部类的方法 3 18 } 19 } 20 21 public void inner2() { 22 System.out.println("我是外部类的方法"); //我是外部类的方法 23 ClassDemo classDemo=new ClassDemo(); 24 classDemo.Demo(); 25 } 26 }
第二种写法
1 import java.lang.reflect.Method; 2 3 import com.preview.seven.InnerDemo.ClassDemo; 4 5 public class InnerClass { 6 public static void main(String[] args) { 7 InnerDemo.ClassDemo classDemo=new InnerDemo().new ClassDemo(); 8 classDemo.Demo(); 9 } 10 } 11 12 class InnerDemo { 13 private int num = 3; 14 15 class ClassDemo { 16 public void Demo() { 17 System.out.println("我是内部类的方法" + " " + num); // 我是内部类的方法 3 18 } 19 } 20 21 public void inner2() { 22 System.out.println("我是外部类的方法"); 23 24 } 25 }
例
1 import java.lang.reflect.Method; 2 3 import com.preview.seven.InnerDemo.ClassDemo; 4 5 public class InnerClass { 6 public static void main(String[] args) { 7 InnerDemo.ClassDemo classDemo = new InnerDemo().new ClassDemo(); 8 classDemo.Demo(); 9 } 10 } 11 12 class InnerDemo { 13 private int num = 3; 14 15 class ClassDemo { 16 private int num=4; 17 18 public void Demo() { 19 System.out.println("我是内部类的方法" + " " + num); // 我是内部类的方法 4 20 System.out.println("我是内部类的方法" + " " + InnerDemo.this.num); // 我是内部类的方法 3 21 } 22 } 23 24 public void inner2() { 25 System.out.println("我是外部类的方法"); 26 27 } 28 }
例4
1 import java.lang.reflect.Method; 2 3 import com.preview.seven.InnerDemo.ClassDemo; 4 5 public class InnerClass { 6 public static void main(String[] args) { 7 8 new InnerDemo.ClassDemo().Demo(); 9 } 10 } 11 12 class InnerDemo { 13 private static int num = 3; 14 15 static class ClassDemo { 16 17 public void Demo() { 18 System.out.println("我是内部类的方法" + " " + num); // 我是内部类的方法 3 19 } 20 } 21 22 public void inner2() { 23 System.out.println("我是外部类的方法"); 24 25 } 26 }
例5
1 public class InnerClass { 2 public static void main(String[] args) { 3 InnerDemo.ClassDemo.Demo(); 4 } 5 } 6 7 class InnerDemo { 8 private static int num = 3; 9 10 static class ClassDemo { 11 12 public static void Demo() { 13 System.out.println("我是内部类的方法" + " " + num); // 我是内部类的方法 3 14 } 15 } 16 17 public void inner2() { 18 System.out.println("我是外部类的方法"); 19 20 } 21 }
例6
1 import java.lang.reflect.Method; 2 3 import com.preview.seven.InnerDemo.ClassDemo; 4 5 public class InnerClass { 6 public static void main(String[] args) { 7 InnerDemo.ClassDemo.Demo(); 8 } 9 } 10 11 class InnerDemo { 12 private static int num = 3; 13 14 class ClassDemo { 15 16 public static void Demo() { 17 System.out.println("我是内部类的方法" + " " + num); // 我是内部类的方法 3 18 } 19 } 20 21 public void inner2() { 22 System.out.println("我是外部类的方法"); 23 24 } 25 }
视图

例7
1 import java.lang.reflect.Method; 2 3 import com.preview.seven.InnerDemo.ClassDemo; 4 5 public class InnerClass { 6 public static void main(String[] args) { 7 InnerDemo innerDemo=new InnerDemo(); 8 innerDemo.inner2(); 9 } 10 } 11 12 class InnerDemo { 13 private static int num = 3; 14 15 class ClassDemo { 16 17 public void Demo() { 18 System.out.println("我是内部类的方法" + " " + num); // 我是内部类的方法 3 19 } 20 } 21 22 public static void inner2() { 23 new ClassDemo().Demo(); 24 25 } 26 }
视图

例8
1 import java.lang.reflect.Method; 2 3 public class InnerClass { 4 public static void main(String[] args) { 5 InnerDemo innerDemo = new InnerDemo(); 6 innerDemo.method(); 7 8 } 9 } 10 11 class InnerDemo { 12 private int x = 3; 13 14 public void method() { 15 int y = 10; 16 17 class Demo { 18 19 void methodDemo() { 20 System.out.println("我是局部内部类中的方法" + " " + y); // 我是局部内部类中的方法 3 21 22 } 23 } 24 25 new Demo().methodDemo(); 26 } 27 28 }
视图

例9
情况一,不会出错
1 import java.lang.reflect.Method; 2 3 public class InnerClass { 4 public static void main(String[] args) { 5 InnerDemo innerDemo = new InnerDemo(); 6 innerDemo.method(10); 7 innerDemo.method(75); 8 9 } 10 } 11 12 class InnerDemo { 13 private int x = 3; 14 15 public void method(final int a) { 16 final int y = 10; 17 18 class Demo { 19 20 void methodDemo() { 21 System.out.println("我是局部内部类中的方法" + " " + a); // 我是局部内部类中的方法 10 22 // 我是局部内部类中的方法75 23 24 25 } 26 } 27 28 new Demo().methodDemo(); 29 } 30 31 }
解析
在这个代码中,虽然final定义的内容只能初始化一次,并且无法修改,但是当第一次调用method方法时,系统会在栈内存中创建一个final a,但是当第一个method调用完成后,这个栈中的a就会销毁,当第二次调用method方法时,系统会在栈内存重新定义一个final a,所以两次调用method方法所使用的a不是同一个,所以调用两次都会输出不同的结果
视图

情况二,会出错
1 import java.lang.reflect.Method; 2 3 public class InnerClass { 4 public static void main(String[] args) { 5 InnerDemo innerDemo = new InnerDemo(); 6 innerDemo.method(10); 7 innerDemo.method(75); 8 9 } 10 } 11 12 class InnerDemo { 13 private int x = 3; 14 15 public void method(final int a) { 16 17 a++; 18 final int y = 10; 19 class Demo { 20 21 void methodDemo() { 22 System.out.println("我是局部内部类中的方法" + " " + a); 23 24 } 25 } 26 27 new Demo().methodDemo(); 28 } 29 30 }
视图

例10
原代码
1 import java.lang.reflect.Method; 2 3 public class InnerClass { 4 public static void main(String[] args) { 5 InnerDemo innerDemo=new InnerDemo(); 6 innerDemo.test01(); 7 } 8 } 9 10 abstract class AbsDemo { 11 abstract void show(); 12 } 13 14 class InnerDemo { 15 int a = 0; 16 17 class Demo01 extends AbsDemo { 18 void show() { 19 System.out.println("我是改写为匿名内部类之前的代码"+" "+a); //我是改写为匿名内部类之前的代码 0 20 21 } 22 } 23 24 void test01(){ 25 new Demo01().show(); 26 } 27 }
改为内部类代码
1 import java.lang.reflect.Method; 2 3 public class InnerClass { 4 public static void main(String[] args) { 5 InnerDemo innerDemo = new InnerDemo(); 6 innerDemo.test01(); 7 } 8 } 9 10 abstract class AbsDemo { 11 abstract void show(); 12 } 13 14 class InnerDemo { 15 int a = 0; 16 17 void test01() { 18 new AbsDemo() { 19 void show() { 20 System.out.println("我是改写为匿名内部类之后的代码" + " " + a); //我是改写为匿名内部类之后的代码 0 21 22 } 23 }.show(); 24 } 25 26 }
例11
匿名内部类一次只能调用一个方法
1 import java.lang.reflect.Method; 2 3 public class InnerClass { 4 public static void main(String[] args) { 5 InnerDemo innerDemo = new InnerDemo(); 6 innerDemo.test01(); 7 } 8 } 9 10 abstract class AbsDemo { 11 abstract void show(); 12 } 13 14 class InnerDemo { 15 int a = 0; 16 17 void test01() { 18 new AbsDemo() { 19 void show() { 20 System.out.println("我是改写为匿名内部类之后的代码" + " " + a); // 我是改写为匿名内部类之后的代码 21 // 0 22 23 } 24 25 void asd() { 26 System.out.println("我是内部类自己的方法" + a); 27 } 28 29 }.asd(); // 我是内部类自己的方法0 30 31 32 new AbsDemo() { 33 void show() { 34 System.out.println("我是改写为匿名内部类之后的代码" + " " + a); // 我是改写为匿名内部类之后的代码 0 35 36 37 } 38 39 void asd() { 40 System.out.println("我是内部类自己的方法" + a); 41 } 42 43 }.show(); //我是改写为匿名内部类之后的代码 0 44 45 } 46 47 }

浙公网安备 33010602011771号