内部类
一个类的内部包含另一个类
成员内部类
修饰符 class 类名 {
修饰符 class 内部类名称{
// 内容
}
}
内用外 随意访问
外用内 需要内部类对象
public class Outside{
public class Inside{
System.out,println("Inside"+ name); // 可以访问外边的成员变量
}
private String name;
public void method(){
System.out.println("Outside");
}
public static void main(String []args){
Outide.Inside inside = new Inside();
}
}
使用内部类
- 间接方式:在外部类的方法中 使用内部类;在main中只调用外部类的方法
- 直接方式:公式
类名称 对象名 = new 外部类名称().new 内部类名称();
局部内部类
定义在一个方法内部
在一个方法内部才能使用 出了这个方法就无法使用
public class 外部类名称{
public 返回值类型 外部类方法名称(参数列表){
class 局部内部类名称{
//内容
}
}
}
public class Outside(){
public void methodOuter(){
class Inside{
int num=10;
public void methodInner(){
System.out.println(num);
}
}
Inside inside = new Inside();
inside.mehodInner();
}
}
权限修饰规则
- 外部类: public / (default)
- 成员内部类 public / protected / (default) / private
- 局部内部类: 什么都不写
final与局部内部类
局部内部类 如果希望访问所在方法的局部变量 那么这个局部变量必须有效 final
但 从Java8 开始 只要局部变量事实不变 final 关键字可以省略
new 出来的对象在堆内存中
局部变量跟着方法走 在栈内存中
方法运行结束后 立刻出栈 局部变量立刻消失
new 出来的对象会在堆中 持续存在 直到垃圾回收消失
public class Outside{
public void methodOutside(){
int num =10; // 这个num比对象先消失
class Inside{
public void methodInsdie(){
System.out.println(num);// 会copy一个num
}
}
}
}
匿名内部类
接口的实现类(或者父类的子类)只需要使用的唯一一次
那么可以省略该类的定义 改为使用匿名内部类
创建对象时 只能使用一次
希望同一个对象 调用多次方法 就必须起名
每个方法只能使用一次
匿名对象无法调用第二次方法 必须再次创建
如果希望使用多次 就需要使用实现类
匿名内部类省略了实现类 匿名对象省略了对象名称
接口名称 对象名称 = new 接口名称(){
//覆盖重写所有抽象方法
}
public class Main{
public static void main(String []args){
MyInterface obj = new MyInterface(){
@Override
//重写方法
public void method(){
System.out.println("匿名内部类实现的方法");
}
public void method2(){
System.out.println("另一个方法")
}
}
obj.method();
obj.method2();
new MyInterface(){
@Override
//重写方法
public void method(){
System.out.println("匿名内部类实现的方法");
}
}.method();
}
}