类包含五大成员:属性、方法、构造器、代码块、内部类。
一.内部类基本语法:
2.内部类的分类:(4种)
(1)定义在外部类局部位置上(如方法中):
局部内部类(有类名)、匿名内部类!!(无类名)
(2)定义在外部类成员位置上:
成员内部类(没有static)、静态内部类(有static)
①局部内部类:
1.可以直接访问外部类的所有成员,包含私有
2.不能添加访问修饰符(?:因为局部内部类相当于局部变量,局部变量不能用访问修饰符修饰!!!),但可用final修饰(表示不能继承)
3.作用域:只能在定义的方法体或代码块中(参考局部变量 )
4.外部类访问局部内部类: 外部类在方法中,创建内部类对象,然后调用方法即可
5.外部其他类不能访问局部内部类
6.当重名时,就近原则 若想访问格式: 外部类名.this.+成员
②匿名内部类:[1本质还是一个类 2内部类 3表层无名字 4还是一个对象!!]
简化开发,只使用一次!
1.不能添加访问修饰符
2.作用域:只能在定义的方法体或代码块中(参考局部变量 )
3.外部其他类不能访问匿名内部类
4.当重名时,就近原则 若想访问格式: 外部类名.this.+成员
基本语法:new 类或接口(参数列表){
类体
};
(1)基于接口的匿名内部类:
interface IA{ //接口
public void cry();
}
IA tiger = new IA() { 重写 cry() } ; //匿名内部类
tiger.cry();
tiger的编译类型:IA tiger的运行类型:匿名内部类【底层有一个类实现了接口!,但我们在表层看不见,底层类的名字:外部类04$1】
jdk在底层创建了匿名内部类,马上创建了对象实例,并把地址返回给tiger
(2)基于类的匿名内部类:(匿名内部类继承外部类 )
Father father = new Father(参数列表){ 重写方法 } ; //匿名内部类
参数列表会传递给构造器
底层有一个类继承了父类!,但我们在表层看不见
jdk在底层创建了匿名内部类,马上创建了对象实例,并把地址返回 (返回对象!!!)
抽象类也如此:必须实现抽象方法
(3.1.0)使用匿名内部类
(1)class Outer05 {
private int n1 = 99;
public void f1() { 基于类的匿名内部类
Person p = new Person(){
@Override
public void hi() {
System.out.println("匿名内部类重写了 hi 方法 n1=" + n1 + " 外部内的n1=" + Outer05.this.n1 ); }
};
}
}
(2)直接调用
new Person(){ 红色的相当于一个对象
@Override
public void hi() {
System.out.println("匿名内部类重写了 hi 方法 n1=" + n1 + " 外部内的n1=" + Outer05.this.n1 ); }
}.hi();
(3.1.1)匿名内部类当实参直接传递
public class InnerClassExercise01 {
public static void main(String[] args) {
//当做实参直接传递,简洁高效
f1(new IL() {
@Override
public void show() {
System.out.println("这是一副名画~~...");
}
});
//传统方法
f1(new Picture());
}
interface IL {
void show();
}
//静态方法,形参是接口类型
public static void f1(IL il) {
il.show();
}
}
//传统方法
//类->实现 IL => 编程领域 (硬编码)
class Picture implements IL {
@Override
public void show() {
System.out.println("这是一副名画 XX...");
}
}
③成员内部类(定义在外部类的成员位置)
1.可以直接访问外部类所有成员,包含私有
2.可以添加任意修饰符 【成员变量】
3.外部类访问成员内部类: 方法中创建成员内部类的对象,然后调用
4.外部其他类使用成员内部类两种方式:
(1):外部类名.内部类名 对象名 = 外部类名.new 内部类名()【相当于外部类的一个成员】
(2):在外部类中写一个方法,然后返回一个内部类实例
public Inner08 getInner08Instance(){ 红色:需要加上内部类名字
return new Inner08(); 返回一个实例
}
Outer08.Inner08 inner08Instance = outer08.getInner08Instance(); 拿到实例
inner08Instance.say(); 调用方法
④静态内部类(定在成员位置,但用 static修饰)
class Outer10 { //外部类
private int n1 = 10;
private static String name = "张三";
//Inner10 就是静态内部类
//1. 放在外部类的成员位置
//2. 使用 static 修饰
//3. 可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员
//4. 可以添加任意访问修饰符(public、protected 、默认、private),因为它的地位就是一个成员
//5. 作用域 :同其他的成员,为整个类体
static class Inner10 {
private static String name = "教育";
public void say(){
System.out.println(name + " 外部类 name= " + Outer10.name);
}
}
1.静态内部类访问外部类: 直接访问所有静态成员
2.外部类访问静态内部类: 在外部类方法中创建静态内部类对象再访问
注:不能直接在外部类中创建对象,否则会调用不了静态内部类方法
class BB{ //外部类 public void m1(){ CC cc = new CC(); cc.show(); } static class CC{ //静态内部类 public void show(){ System.out.println("sdd"); } } }
3.外部其他类访问:
(1):通过类名直接访问(满足访问权限)
(2):写一个方法,返回静态内部类对象实例
public Inner10 getInner10() {
return new Inner10();
}
public static Inner10 getInner10_() {
return new Inner10();
}