一、内部类
1、概述
- 把类定义在其他类的内部
2、内部类的访问特点
- 内部类可以直接访问外部类的成员,包括私有
- 外部类要访问内部类的成员,必须创建对象
class Outer{ private int num = 10; class Inner{//内部类 public void show(){//内部类成员方法 System.out.println("这是内部类是 show 方法"); } } public void method(){//成员方法 Inner in = new Inner();//创建对象,new 出内部类的成员方法 in.show(); } } public class InnerClassDemo { public static void main(String[] args){ Outer ou = new Outer();//实例化外部类的成员方法 ou.method();//输出:这是内部类是 show 方法 } }
二、成员内部类
1、按照内部类在类中的定义位置:
- 成员位置(成员内部类)
- 局部位置(局部内部类)
class Outer{ private int num = 10; class Inner1{//在成员位置,成员内部类 public void show(){//内部类成员方法 System.out.println("这是内部类是 show 方法"); } } public void method(){//成员方法 class Inner2{//在局部的位置,局部内部类 public void method(){ System.out.println("这是局部内部类的 method 方法"); } } } } public class InnerClassDemo { public static void main(String[] args){ } }
2、成员内部类,外界如何创建对象(一般内部类就是不让外界访问)
外部类名.内部类名 对象名 = 外部类对象.内部类对象
Outer.Inner in = new Outer().new Inner();
class Outer{ private int num = 10; class Inner{//在成员位置,成员内部类 public void show(){ System.out.println("在成员方法的位置,成员内部类,show方法"); } } } public class InnerClassDemo{ public static void main(String[] args){ //需求:访问成员内部类的 show 方法 Outer.Inner in = new Outer().new Inner();//注意书写 in.show(); } }
3、成员内部类,常见修饰符
- private 为了保证数据的安全性
- 为了让数据访问更方便
4、注意:静态内部类访问的外部类数据必须用静态修饰。
class Outer{
private int num1 = 10;
private static int num2 = 20;
public static class Inner{//静态成员内部类,
public void show1(){
//System.out.println("内部类里的 show 方法"+num1);//静态内部类访问外部类数据,外部数据必须静态修饰,无法访问num1
System.out.println("内部类里的 show 方法"+num2);//可以访问 num2 的值,因为 num2 被静态修饰
}
public static void show2(){
//System.out.println("内部类里的 show 方法"+num1);
System.out.println("内部类里的 show 方法"+num2);//可以访问外部类的 num2 的值
}
}
}
class InnerClassDemo{
public static void main(String[] args){
//使用静态内部类,下面这个是错误的
// Outer.Inner in1 = new Outer().new Inner();
// in1.show1();
// in1.show2();
Outer.Inner in2 = new Outer.Inner();//成员内部类被静态修饰后的访问方式
in2.show1();
in2.show2();
//Outer.Inner.show1();//无法调用,内部类 Inner 的show1 方法没有被静态修饰
Outer.Inner.show2();//可以调用
}
}
三、局部内部类
1、按照内部类在类中的定义位置:
- 成员位置(成员内部类)
- 局部位置(局部内部类)
2、局部内部类特点
- 可以直接访问外部类的成员
- 可以创建内部类对象,通过对象调用内部类方法,来使用内部类
3、局部内部类访问局部变量必须用 final 修饰
- 因为局部变量会随着方法的调用完毕而消失,这时候,局部对象并没有立马从堆内存中消失,还要使用那个变量。为了让数据还能继续被使用,就用 final 修饰,这样,在堆内存里面就是一个常量。
class Outer{ private int num1 = 10; public void show(){ int num2 = 20; final int num3 = 30; class Inner{ public void method(){ System.out.println(num1);//可以直接访问外部类的成员变量 System.out.println("_________"); System.out.println(num2); System.out.println(num3); } } System.out.println(num2); System.out.println(num3); Inner in1 = new Inner(); in1.method(); } } class InnerClassDemo{ public static void main(String[] args){ Outer ou1 = new Outer(); ou1.show(); } }
四、匿名内部类
1、概述
- 内部类的简化写法
2、前提
- 存在一个类或者接口(可以是具体类或者是抽象类)
3、格式
new 类名(){重写方法}
4、本质
- 是一个继承了类或者实现了接口的子类匿名对象
5、实例
局部内部类是实现(普通写法)
interface Jiekou{
void show();//接口里的成员方法必须是抽象方法,后面不能有 {} ,默认可以省略 public abstract
}
public class InnerClassDemo{
public void method(){
class Inner implements Jiekou{//局部内部类实现接口
public void show(){
System.out.println("局部内部类实现 show 方法");
}
}
Jiekou j = new Inner();//多态
j.show();
}
public static void main(String[] args){
InnerClassDemo in = new InnerClassDemo();
in.method();//输出:局部内部类实现 show 方法
}
}
使用匿名内部类,局部内部类是实现
interface Jiekou{
void show();//接口里的成员方法必须是抽象方法,后面不能有 {} ,默认可以省略 public abstract
}
public class InnerClassDemo{
public void method(){
//使用局部内部类的实现
// class Inner implements Jiekou{//局部内部类实现接口
// public void show(){
// System.out.println("局部内部类实现 show 方法");
// }
// }
// Jiekou j = new Inner();//多态
// j.show();
//使用匿名内部类的实现
//接口用于匿名内部类的时候是可以实例化的
Jiekou j = new Jiekou() {
@Override
public void show() {
System.out.println("匿名内部类的实现 show 方法");
}
};
j.show();
}
public static void main(String[] args){
InnerClassDemo in = new InnerClassDemo();
in.method();
}
}
注意:
- 上面两种方法是等价的