7、内部类
知识点:内部类
含义:一个类里面声明一个类
7.1、成员内部类
特点:可以调用外部类中所有的属性
package com.dream.outter_inner_01;
//外部类
public class Outter {
private String str1 = "aaa";
String str2 = "bbb";
protected String str3 = "ccc";
public String str4 = "ddd";
final String str5 = "eee";
static String str6 = "fff";
//成员内部类
class Inner{
private String str1 = "成员内部里的属性~~~";
public void method(){
System.out.println("成员内部类里的方法");
System.out.println(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
}
}
}
package com.dream.outter_inner_01;
import com.dream.outter_inner_01.Outter.Inner;
public class Test01 {
public static void main(String[] args)
//创建成员内部类对象
Inner inner = new Outter().new Inner();
//调用方法
inner.method();
}
}
7.2、静态内部类
特点:只能到调用外部类的静态属性
package com.dream.outter_inner_02;
//外部类
public class Outter {
static String str6 = "fff";
//静态内部类
static class Inner{
public void method(){
System.out.println("静态内部类里的方法");
//静态内部类不能调用外部类的成员变量
System.out.println(str6);//Outter.str6
}
}
}
7.3、接口内部类
注意:接口内部类底层就是静态内部类
package com.dream.outter_inner_03;
//接口
public interface Outter {
//接口内部类 默认添加public static
class Inner{
public void method(){
System.out.println("接口内部类里的方法");
}
}
}
7.4、局部内部类
案例一:
package com.dream.outter_inner_04;
//外部类
public class Outter {
public void function(){
//局部内部类
class Inner{
public void method(){
System.out.println("局部内部类里的方法");
}
}
//创建局部内部类的对象
Inner inner = new Inner();
//调用方法
inner.method();
}
}
案例二:
package com.dream.outter_inner_05;
//外部类
public class Outter {
public Object function(){
//如果局部内部类中使用到该变量,JDK1.8开始该变量自动变成常量
//因为防止i在该方法结束后才使用
int i = 100;
//局部内部类
class Inner{
@Override
public String toString() {
return i+"";
}
}
//创建局部内部类的对象
Inner inner = new Inner();
return inner;
}
}
//测试类
package com.dream.outter_inner_05;
public class Test01 {
public static void main(String[] args) {
//创建外部类的对象
Outter outter = new Outter();
//调用方法
Object obj = outter.function();
System.out.println(obj);
}
}
7.5、匿名内部类
接口匿名内部类:
package com.dream.outter_inner_06;
public interface I1 {
public void method();
}
//测试类
package com.dream.outter_inner_06;
public class Test02 {
public static void main(String[] args) {
//1.创建匿名实现类,实现I1中的method
//2.创建匿名实现类的对象,指向接口的引用
I1 i1 = new I1() {
@Override
public void method() {
}
};
}
}
抽象匿名内部类:
package com.dream.outter_inner_06;
public abstract class A {
public abstract void method();
}
//测试类
package com.dream.outter_inner_06;
public class Test01 {
public static void main(String[] args) {
//1.创建匿名子类,继承A,重写method
//2.创建匿名子类对象,赋值给父类的引用
A a = new A() {
@Override
public void method() {
}
};
}
}
7.6、内部类总结:
内部类的应用场景1:
如果一个类的对象只在另外一个类中使用,
就可以考虑把该类变成成员内部类或者静态内部类,
如果内部类要用到外部类的所有属性就把该类变成成员内部类,
如果内部类只用到外部类的静态属性就把给类变成静态内部类
内部类的应用场景2:
如果一个类的对象只在另外一个类的方法中使用,就可以考虑把该类变成局部内部类,一般不使用这种设计思想
内部类的应用场景3:
如果一个类的对象只在接口中使用,就可以考虑把该类变成接口内部类,一般不使用这种设计思想
内部类的应用场景4:
抽象类子类的对象或者是接口实现类对象只使用到一次,就可以考虑使用匿名内部类