目录
1.1 概念
在类的内部定义的类,叫做内部类。
内部类有:
-
成员内部类
-
静态内部类
-
局部内部类
-
匿名内部类
在类的内部定义类,相当于把该类定义为私有类,一般是封装思想的体现。
内部类的定义和使用跟变量相似。
public class Demo1 { //成员变量 String name = ""; //静态变量 final String name1 = ""; public void m1() { //局部变量 String name2 = ""; } }
1.2 成员内部类【了解】
成员内部类是直接在类中定义的普通类。
public class Member_innerClass { String name = "OuterClass"; //创建成员内部类 class C1 { //内部类的属性 String name = "InnerClass"; void m1() { System.out.println(name); //调用外部类的name System.out.println(Member_innerClass.this.name); System.out.println("成员内部类方法"); } //局部内部类不能创建静态属性和方法 // static int a = 10; // static void m2(){ // System.out.println("成员内部类静态方法"); // } } } public class Demo1 { public static void main(String[] args) { //先实例化外部类 Member_innerClass a1 = new Member_innerClass(); //通过外部类对象创建内部类的对象 Member_innerClass.C1 c1 = a1.new C1(); //Member_innerClass.C1 c1 = new Member_innerClass().new C1(); //使用内部类方法 c1.m1(); //InnerClass //OuterClass //成员内部类方法 // System.out.println(c1.a); // c1.m2(); } }
由于内部类嵌套在外部类中,因此必须首先实例化外部类,然后创建内部类的对象来实现,然而静态属性和方法可以创建对象就能使用,所以内部类无法创建静态的属性和方法。
结论
-
不能创建静态属性
-
不能创建静态方法
-
在内部类的方法中,若想调用外部类的属性,可直接调用,但内部类中有与之同名的局部属性,则需要使用外部类的类名.this.属性名 来调用外部类的属性。
-
成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。
-
局部内部类创建对象依赖于外部类,创建对象格式如下:
//通过外部类对象创建内部类的对象 外部类名.内部类名 c1 = 外部类对象.new 内部类名(); //Member_innerClass.C1 c1 = new Member_innerClass().new C1();
1.3 静态内部类【重点】
静态内部类是在类中定义的静态类,使用方式与普通类一样,一般在项目中使用静态内部类来体现封装特性。
静态内部类是不需要依赖于外部类的,因此不能使用外部类的非static成员变量或者方法,因为外部类非static成员变量或方法依赖与具体对象。
public class Static_InnerClass { String name = "外部类非static属性"; static String name1 = "外部类static属性"; static class StaticClass{ String name = "内部类非static属性"; static String name1 = "内部类static属性"; //创建静态内部类的静普通方法 void m1(){ System.out.println(name); System.out.println(name1); //无法访问外部类非static属性 // System.out.println(Static_InnerClass.this.name); System.out.println(Static_InnerClass.name1); System.out.println("内部类非static方法"); } //创建静态内部类的静态方法 static void m2(){ //静态方法无法调用非static的属性 // System.out.println(name); System.out.println(name1); //无法访问外部类非static属性 // System.out.println(Static_InnerClass.this.name); System.out.println(Static_InnerClass.name1); System.out.println("内部类static方法"); } } } public class Demo1 { public static void main(String[] args) { Static_InnerClass s1 = new Static_InnerClass(); //调用静态内部类中的static方法或属性时,直接使用外部类名.内部类名.方法名 访问 Static_InnerClass.StaticClass.m2(); //调用静态内部类中的非static方法或属性,需要先创建静态内部类对象再调用方法和属性 Static_InnerClass.StaticClass sc1 = new Static_InnerClass.StaticClass(); sc1.m1(); //内部类static属性 //外部类static属性 //内部类static方法 //内部类非static属性 //内部类static属性 //外部类static属性 //内部类非static方法 } }
结论
-
静态内部类只能访问外部类的静态属性和方法。
-
静态内部类中可以定义静态的也可以定义非静态的属性和方法。
-
静态内部类中定义的静态方法只能访问静态属性·。
-
静态内部类中定义的非静态方法可以访问外部类静态属性和方法和内部类的所有属性和方法。
-
-
静态内部类创建对象不依赖与外部类,创建对象格式如下:
外部类名.内部类名 变量名 = new 外部类名.内部类名();
-
访问静态内部类的静态属性和方法时,可以直接使用 外部类名.内部类名.方法名 来调用。
-
访问静态内部类的非静态属性和方法时,要创建内部类的实例对象,然后才能访问。
-
因为静态内部类定义和使用起来与普通类相似,所以是重点。
1.4 局部内部类【了解】
在类的方法中定义的类称为局部内部类。
不能创建静态成员和方法
不能在前面添加public、private等修饰
要在定义后立即使用,否则出了作用域就无法使用
public class Local_InnerClass { public void m1(){ String name = "局部属性"; //不能使用public等修饰符 class LocalClass { String name = "局部内部类"; static String name1 = "局部内部类静态属性"; public void localM1(){ System.out.println(name); System.out.println(name1); System.out.println("局部内部类方法"); } } LocalClass l1 = new LocalClass(); l1.localM1(); } }
结论
-
局部内部类必须在定义后立即使用
-
局部内部类无法在main中new一个对象
-
局部类内部类定义后,在该方法中创建对象,然后调用内部类的方法和属性。
-
局部内部类只能使用类中定义的变量和方法
-
局部内部类无法创建静态属性和方法,因为局部内部类需要实例化后才能使用。
1.5 匿名内部类【重点】
当需要将一个抽象类或者接口创建对象时,会要求继承该抽象类或实现接口才可创建对象。如果需要直接对该抽象类或接口创建对象,且只使用一次时,可使用匿名内部类的方式。
//定义一个抽象类 public abstract class A { void show() { } } public abstract class B { } public class Demo1 { public static void main(String[] args) { //通过匿名内部类使抽象类能够创建对象 A a = new A(){ @Override void show() { System.out.println("通过匿名内部类创建对象"); } }; a.show(); //通过匿名内部类使用方法,只能使用一次 new A(){ @Override void show() { System.out.println("匿名内部类"); } }.show(); //当抽象类没有方法时,匿名内部类可以这样定义 new B(){}; } }
结论
-
匿名内部类,就是没有名字的一种嵌套类,不需要单独创建一个类就可创建一个对象。
-
匿名内部类只能使用一次
-
匿名内部类在编译期间,会生成一个名称以
$编号
结尾的class文件,所以他被识别成一个真实的类。 -
匿名内部类可以用在具体类、抽象类、接口上,且对方法个数没有要求。