内部类
1、理解
它允许在一个类的内部定义另一个类
2、分类
成员内部类
静态内部类
接口内部类
局部内部类
匿名内部类
3、用途
实现回调:通过内部类可以方便地实现回调接口。
简化代码结构:可以将一些与外部类紧密相关的类定义在内部,使代码更加紧凑。
封装实现细节:内部类可以隐藏一些实现细节,只暴露必要的接口给外部类使用。
访问外部类的私有成员:内部类可以无限制地访问外部类的私有成员。
1、成员内部类
定义在类的成员位置(即不在任何方法内),可以无限制地访问外部类的所有成员(包括私有成员)。
成员内部类不能定义静态成员(除静态常量外),因为它与外部类的实例相关联。
外部类的一个实例持有内部类的一个实例的引用,但反过来则不一定。
成员内部类可以通过外部类的实例来创建(使用外部类实例.new 内部类())。
package com.qf.outter_inner_02; //外部类 public class Outter { private String str1 = "属性1"; String str2 = "属性2"; protected String str3 = "属性3"; public String str4 = "属性4"; final String str5 = "属性5"; static String str6 = "属性6"; static final String str7 = "属性7"; //成员内部类 class Inner{ String str1 = "成员内部类的属性"; public void method(){ System.out.println("成员内部类的方法"); System.out.println(str1);//this.str1 System.out.println(Outter.this.str1); System.out.println(str2);//Outter.this.str2 System.out.println(str3);//Outter.this.str3 System.out.println(str4);//Outter.this.str4 System.out.println(str5);//Outter.this.str5 System.out.println(str6);//Outter.str6 System.out.println(str7);//Outter.str7 } } }
package com.qf.outter_inner_02; import com.qf.outter_inner_02.Outter.Inner; public class Test01 { /** * 知识点:成员内部类 * * 需求:创建成员内部类的对象,并调用方法 * * 小结: * 1.创建成员内部类对象,必须先创建外部类对象,再创建内部类对象 * 2.成员内部类可以使用外部类所有的属性 */ public static void main(String[] args) { Inner inner = new Outter().new Inner(); inner.method(); } }
2、静态内部类
使用
static
关键字修饰的内部类。它与外部类没有直接的实例关联,只能访问外部类的静态成员。
可以定义静态成员。
创建静态内部类的实例不需要外部类的实例(使用外部类名.内部类名)。
package com.qf.outter_inner_03; //外部类 public class Outter { static String str1 = "属性1"; static final String str2 = "属性2"; //静态内部类 static class Inner{ public void method(){ System.out.println("静态内部类的方法"); System.out.println(str1);//Outter.str6 System.out.println(str2);//Outter.str7 } } }
package com.qf.outter_inner_03; import com.qf.outter_inner_03.Outter.Inner; public class Test01 { /** * 知识点:静态内部类 * * 需求:创建静态内部类的对象,并调用方法 * * 小结: * 1.创建静态内部类对象,不用创建外部类对象 * 2.静态内部类只能使用外部类的静态属性 */ public static void main(String[] args) { Inner inner = new Outter.Inner(); inner.method(); } }
3、接口内部类
* 知识点:接口内部类 * * 需求:创建接口内部类的对象,并调用方法 * * 小结: * 1.接口内部类就是静态内部类 * 2.接口内部类默认使用public static修饰
package com.qf.outter_inner_04; //外部接口 public interface Outter { //接口内部类 //public static class Inner{ class Inner{ public void method(){ System.out.println("接口内部类的方法"); } } }
package com.qf.outter_inner_04; import com.qf.outter_inner_04.Outter.Inner; public class Test01 { /** * 知识点:接口内部类 * * 需求:创建接口内部类的对象,并调用方法 * * 小结: * 1.接口内部类就是静态内部类 * 2.接口内部类默认使用public static修饰 */ public static void main(String[] args) { Inner inner = new Outter.Inner(); inner.method(); } }
4、局部内部类
定义在方法或代码块中。
局部内部类可以访问外部类的所有成员,以及它所在方法或代码块中的局部变量(只要这些变量是
final
或等效于final
的)。局部内部类不能定义静态成员。
局部内部类的可见性、生命周期与所在方法或代码块相同。
1·、
package com.qf.outter_inner_05; //外部类 public class Outter { public void method(){ //局部内部类 class Inner{ public void innerMethod(){ System.out.println("局部内部类里的方法"); } } //创建局部内部类对象 Inner inner = new Inner(); inner.innerMethod(); } }
package com.qf.outter_inner_05; public class Test01 { /** * 知识点:局部内部类 * * 需求:调用局部内部类里的方法 * * 小结: * 局部内部类不能使用访问修饰符修饰(因为局部内部类的作用域就是在该方法内) */ public static void main(String[] args) { Outter outter = new Outter(); outter.method(); } }
2、
package com.qf.outter_inner_06; //外部类 public class Outter { public void method(){ int i = 100; //局部内部类 class Inner{ public void innerMethod(){ System.out.println("局部内部类里的方法:" + i); } } //创建局部内部类对象 Inner inner = new Inner(); inner.innerMethod(); } }
package com.qf.outter_inner_06; public class Test01 { /** * 知识点:局部内部类 * * 注意:局部内部类使用到外部类方法里的变量,该变量在JDK1.8开始会自动变成常量 */ public static void main(String[] args) { Outter outter = new Outter(); outter.method(); } }
3、
package com.qf.outter_inner_07; //外部类 public class Outter { public Object method(){ int i = 100; //局部内部类 class Inner{ @Override public String toString() { return "局部内部类里的方法:" + i; } } //创建局部内部类对象 Object obj = new Inner(); return obj; } }
package com.qf.outter_inner_07; public class Test01 { /** * 知识点:局部内部类 * * 注意:局部内部类使用到外部类方法里的变量,该变量在JDK1.8开始会自动变成常量 */ public static void main(String[] args) { Outter outter = new Outter(); Object obj = outter.method(); System.out.println(obj.toString()); } }
5、匿名内部类
没有类名的内部类,通常用于实现接口或继承父类。
常用于与接口或抽象类交互的场合,如事件处理、适配器模式等。
匿名内部类不能定义任何静态成员。
匿名内部类通常作为方法参数或立即赋值给某个变量。
package com.qf.outter_inner_08; public abstract class A { public abstract void method(); }
package com.qf.outter_inner_08; public class Test01 { /** * 知识点:匿名内部类 */ public static void main(String[] args) { //1.底层创建匿名类(Test01$1.class),继承A类,重写method() //2.创建匿名类对象 //3.将匿名类对象的内存地址赋值给父类的引用 -- 多态 A a = new A() { @Override public void method() { // TODO Auto-generated method stub } }; a.method(); } }
package com.qf.outter_inner_09; public interface I1 { public void method(); }
package com.qf.outter_inner_09; public class Test01 { /** * 知识点:匿名内部类 */ public static void main(String[] args) { //1.底层创建匿名类(Test01$1.class),实现I1接口中的method() //2.创建匿名类的对象 //3.将匿名类对象的内存地址赋值给接口的引用 -- 多态 I1 i1 = new I1() { @Override public void method() { } }; i1.method(); } }