内部类
内部类的分类
定义在外部类的局部位置上
1)局部内部类(有类名)
2)匿名内部类(没有类名,重点)
定义在外部成员位置上
1)成员内部类(没用static)
2) 静态内部类 (使用static)
局部内部类:
定义在外部类的局部位置,通常在方法或者代码块。
可以直接访问外部类的成员,包括私有的。
不能添加访问修饰符,但是可以用final修饰。(加final这个局部内部类不能被继承)
作用域:仅仅作用在定义的方法中或者代码块中。
局部内部类直接访问外部类成员。
外部类在方法中可以创建局部内部类实例来调用方法。
外部其他类成员(不包含局部内部类的类)不能访问局部内部类。
外部类和局部内部类成员重名,就近原则。如果想访问外部类的成员,则可以使用(外部类名.this.成员)
—>外部类名.this.成员(外部类名.this就是外部类的对象)
匿名内部类:
1)本质是类 2)内部类 3)该类没有名字 4)同时还是一个对象
定义在外部类的局部位置,通常在方法,并且没有类名
基本语法 -->基于接口
interface IA{
}
外部类的方法中:
编译类型 :接口IA
执行类型:匿名内部类 名称是 : 外部类$1
底层:
class xxx implements IA{
@override
public void cry{
//TODO
}
}
JDk 在创建匿名内部类xxx$1 立马创建了实例 把地址给tiger
匿名内部类使用一次就不能使用了 ,但是tiger对象可以多次使用。
IA tiger = new IA(){
@override
public void cry{
//TODO
}
}
tiger.cry();
tiger.cry();
tiger.cry();
基本语法 -->基于类的匿名内部类
外部类的方法中:
编译类型:Father
运行类型:匿名内部类 外部类$2 (按顺序 123)
Father f = new Father(){
@ovrrride
//重写方法 --->动态绑定,运行类型为外部类$2 所以执行的是重写的方法
};
========
或者直接调用
new Father(){
@ovrrride
//重写方法
}.方法;
使用场景:
匿名内部类直接当参数传递,简介高效
public static void main(String[] args) {
f1(new IA() {
@Override
public void say() {
//TODO
}
});
}
public static void f1(IA ia){
ia.say();
}
interface IA{
void say();
}
成员内部类
细节:
1.定义在外部类的成员位置,没有static修饰
可以直接访问外部类成员
2.可以添加任何修饰符(public 、protected 、默认 、private),因为他的地位就是一个成员
3.作用域:和外部类的其他的成员一样。为整个类
4.成员内部类–>访问—>外部成员类 直接访问
5.外部成员–>访问–>内部类 先创建对象 在访问(可以在外部类写个方法里面创建对象)
6.外部其他类–>访问—>成员内部类
1.外部其他类的实例.new.内部成员类 class.new.class();
2.在外部类写个方法得到成员内部类
7.外部类和成员内部类方法重名时,成员内部类访问就近原则,需要访问外部内成员,
外部类名.this.成员
public class Outer {
public static void main(String[] args) {
AA aa = new AA();
//1.把.new Inner()当做AA 的成员
AA.Inner inner = aa.new Inner();
inner.say();
//2.
AA.Inner inner1 = new AA().getInner();
inner1.say();
//3.
AA.Inner inner2 = new AA().new Inner();
inner2.say();
}
}
class AA{
private String name ="sam";
class Inner {
private int n = 100;
private String name = "jack";
public void say(){
System.out.println("hello"+AA.this.name);
}
}
//2.外部类写方法返回成员内部类
public Inner getInner(){
return new Inner();
}
}
静态内部类
定义在外部类的成员位置,有static修饰
1.可以访问外部类的静态成员
2.可以添加任何访问修饰符
3.作用域:整个外部类
4.静态内部类–>访问–>外部类 直接访问所有静态成员
5.外部类–访问 --静态内部类 —创建对象 访问(外部类写个方法,里面创建内部类然后去访问)
6.外部其他类 访问 静态内部类
- new 外部类.静态内部类
2.编写方法返回静态内部类的对象实例
7.静态内部类成员与外部类成员同名,直接 用外部类.成员名 访问 不用加this,因为访问外部的只能是静态成员
public class StaticInnerClass {
public static void main(String[] args) {
// new Outer01().f1();
//7.1 当做一个静态成员使用
Outer01.Inner01 inner01 = new Outer01.Inner01();
inner01.say();
//7.2写方法获取Inner01实例来使用 普通方法 需要创建外部类先
Outer01 outer02 = new Outer01();
outer02.getInner01().say();
//7.2 写静态方法获取Inner01实例 可以直接用外部类.静态方法
Outer01.getInner01_().say();
}
}
class Outer01{
private int n = 10;
private static String name = "sam";
static class Inner01{
private String name = "jack";
public void say(){
System.out.println("hello motorola");
System.out.println("访问外部成员 name"+Outer01.name);
}
}
public Inner01 getInner01(){
return new Inner01();
}
public static Inner01 getInner01_(){
return new Inner01();
}
public void f1(){
Inner01 inner01 = new Inner01();
inner01.say();
}
}