内部类
成员内部类
-
定义:内部类就是在类的内部定义另一个类
-
使用:
package day1209;
public class Outer1 {
int num = 20;
String name = "Outer1";
public void method(){
System.out.println("这是外部类中的method方法");
}
public void show(){
System.out.println("这是show方法");
}
public void outerMethod(){
//外部类也可以使用内部类的属性和方法 --先创建内部类对象
Inner inner = new Inner();
System.out.println(inner.name);
inner.showMethod();
}
//内部类 -- 直接写在类中 成员内部类
//内部类同样可以使用四种访问权限修饰符来控制访问
private class Inner{
String name = "Inner";
public void method(){
System.out.println("这是内部类中的method方法");
}
public void method2(){
System.out.println("内部类中的方法");
}
public int innerMe(){
return 20;
}
public void showMethod(){
System.out.println("这是内部类中的showMethod方法");
//在内部类中可以直接使用外部类的方法和属性
//1.当属性/方法不同名的时候,可以直接使用
System.out.println(num);
show();
//2.当属性/方法重名的时候,需要强制指定使用外部类
//外部类.this.属性/方法 -- 强制使用同名的外部类中的方法
System.out.println("Outer1.this.name");
Outer1.this.method();
//3.当属性/方法重名的时候,直接使用的时候使用的是内部类中的属性和方法
System.out.println(name);
method();
//Outer1.this.method();
//内部类中可以直接调用自己的方法
method2();
}
}
}
静态内部类
-
定义:使用static修饰的内部类
-
使用:
package day1209;
public class Outer2 {
public static void m1(){
System.out.println("外部类的静态方法");
}
public void m2(){
System.out.println("外部类的非静态方法");
}
public void outerMethod(){
//外部类使用内部类的静态方法
Inner.method();
//外部类中使用内部类的非静态方法
//先创建内部类对象,然后使用
Outer2.Inner inner = new Outer2.Inner();//可以直接写 Inner inner = new Inner();
inner.method2();
}
//如果内部类中存在静态成员--则这个内部类必须时static的
//有静态方法的内部类必定是静态内部类
static class Inner{
public static void method(){
System.out.println("静态内部类中的静态方法");
//内部类使用外部类的静态方法
Outer2.m1();
//内部类使用外部类的非静态方法
//先new出外部类对象
Outer2 outer2=new Outer2();
outer2.m2();
}
public void method2(){
System.out.println("内部类中的非静态方法");
}
}
}
局部内部类
-
定义:定在类中的方法中的内部类叫做局部内部类(用的很少)
-
使用
-
局部内部类的作用范围仅限于本方法中
-
局部内部类在访问他所在方法中的局部变量必须用final修饰
-
局部内部类想要使用局部变量,那么,变量必须变成常量
-
因为当调⽤这个⽅法时,局部变量如果没有⽤final修饰,他的⽣命周期和⽅法的⽣命周期是⼀样的,当⽅法弹栈,这个局部变量也会消失,那么如果局部内部类对象还没有⻢上消失想⽤这个局部变量,就没有了,如果⽤final修饰会在类加载的时候进⼊常量池,即使⽅法弹栈,常量池的常量还在,也可以继续使⽤
-
jdk 1.8 取消的这个定义 , 其实不是取消了, 是设置为了隐式的
-
例子
public class Otuer3 { public void method(){ final String name = "我是你爸爸"; //内部类在方法中--局部内部类 class Inner{ public void method(){ System.out.println("这是局部内部类的方法"); } public void show(){ //局部内部类可以使用方法的变量 System.out.println(name);//局部内部类中使用的局部变量, 建议使用final显式修饰的方式 } } //创建对象的方式使用 Inner inner = new Inner(); inner.method(); inner.show(); } }
-
匿名内部类
-
定义
- 匿名内部类就是局部内部类的简写形式,相当于是⼀个没有名字的普通⼦类/实现类
- 匿名内部类⽤于定义接⼝的或者类的⼦类
-
使用
- 前提是必须存在一个类,或则接口
- 这里的类可以是具体的类也可以是抽象类
- 相当于是有⼀个没有名字的⼦类继承或者实现⼀个类或接⼝,然后重写⾥⾯的⽅法,本质是⼀个继承了该类或者实现了该接⼝的匿名⼦类对象
- 多⽤于规则简单,⼦类使⽤很少的接⼝应⽤中
public void method2(){
class Inner implements A{
@Override
public void show() {
System.out.println("我是A的实现类");
}
}
A a = new Inner();
A a2 = new Inner();
a.show();
a2.show();
//匿名内部类 -- 替代局部内部类
A a1 = new A() {
@Override
public void show() {
System.out.println("这是一个匿名内部类");
}
};
a1.show();
//匿名内部类 --服务对象 任何类都可以使用匿名内部类的方式创建对象
//匿名内部类就是局部内部类的简写形式
//匿名内部类就相当于一个没有名字,没有单独书写的普通子类/实现类
Normal normal = new Normal();
normal.show();
Normal n1 = new Normal(){
@Override
public void show() {
System.out.println("匿名的子类,重写normal的show方法");
}
};
n1.show();
}
在外部使用外部类和内部类的方法/属性
public class OuterDemo {
public static void main(String[] args) {
//在外部使用成员内部类
//1.使用外部类方法
Outer1 outer1 = new Outer1();
outer1.outerMethod();//new Outer1().outerMthod();
new Outer1().outerMethod();
//2.使用成员内部类对象 --当前成员内部类 可以被访问到 --非private修饰
//创建内部类对象
//第一种 --依次创建
Outer1 o1 = new Outer1();
Outer1.Inner inner = o1.new Inner();
inner.method2();
//第二种 -- 单纯创建内部类对象
Outer1.Inner inner1=new Outer1().new Inner();//new Outer1().new Inner().method2();
inner.method2();
//成员方法 new 外部类名.方法名()
// 内部类--看成是一个方法的话 new 类名().内部类
//类 -- 创建对象--构造方法 new 内部类名()
//new 外部类名().new 内部类名();
int i = o1.userInnerMe();
System.out.println(i);
//使用静态内部类
//1.使用静态内部类的非静态方法
//先创建对象
Outer2.Inner inner2 = new Outer2.Inner();
inner2.method2();
//使用静态内部类的静态方法
Outer2.Inner.method();
}
}