内部类
概念:内部类是指在一个类的内部定义的类。它可以访问外部类的私有成员和方法,提供了更好的封装性,可以控制内部类的可访问性。内部类可以是静态的,也可以是私有的,但外部类只能是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
}
}
}
public class Test01 {
public static void main(String[] args) {
Inner inner = new Outter().new Inner();
inner.method();
}
}
小结:
- 创建成员内部类对象,必须先创建外部类对象,再创建内部类对象
- 成员内部类可以使用外部类所有的属性
静态内部类
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
}
}
}
public class Test01 {
public static void main(String[] args) {
Inner inner = new Outter.Inner();
inner.method();
}
}
小结:
- 创建静态内部类对象,不用创建外部类对象
- 静态内部类只能使用外部类的静态属性
接口内部类
interface Outter {
//接口内部类
//public static class Inner{}
class Inner{
public void method(){
System.out.println("接口内部类的方法");
}
}
}
public class Test01 {
public static void main(String[] args) {
Inner inner = new Outter.Inner();
inner.method();
}
}
小结:
- 接口内部类就是静态内部类
- 接口内部类默认使用public static修饰
局部内部类
class Outter {
public void method(){
//局部内部类
int i=100;
class Inner{
public void innerMethod(){
System.out.println("局部内部类里的方法");
System.out.println("局部内部类里的方法"+i);
}
}
//创建局部内部类对象
Inner inner = new Inner();
inner.innerMethod();
}
}
public class Test01 {
public static void main(String[] args) {
Outter outter = new Outter();
outter.method();
}
}
小结:
- 局部内部类不能使用访问修饰符修饰(因为局部内部类的作用域就是在该方法内)
- 局部内部类使用到外部类方法里的变量,该变量在JDK1.8开始会自动变成常量
匿名内部类
interface I1 {
public void method();
}
abstract class A {
public abstract void method();
}
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() {
}
};
a.method();
//1.底层创建匿名类(Test01$1.class),实现I1接口中的method()
//2.创建匿名类的对象
//3.将匿名类对象的内存地址赋值给接口的引用 -- 多态
I1 i1 = new I1() {
@Override
public void method() {
}
};
i1.method();
}
}
总结
- A类的对象只在B类中使用,并且A类使用到B类所有的属性 – 可以将A类设置为B类的成员内部类(常用)
- A类的对象只在B类中使用,并且A类使用到B类的静态属性 – 可以将A类设置为B类的静态内部类(常用)
- A类(抽象类)的子类只创建一次对象,就没必要去创建子类 – 直接使用匿名内部类(new A())(常用)
- I1接口的实现类只创建一次对象,就没必要去创建实现类 – 直接使用匿名内部类(new I1())(常用)
- A类的对象只在B类某个方法中使用 – 可以将A类设置为B类的局部内部类(少见)
- A类的对象只在I1接口中使用 – 可以将A类设置为I1接口的接口内部类(少见)