内容纲要
412!!重\难点讲四种内部类、局部内部类、(超重点)匿名内部类、成员内部类、静态内部类
-
类的五大成员:属性、方法、构造器、代码块、内部类
-
注意内部类是学习的难点,同时也是重点;后面看底层原码有大量的内部类。
局部内部类
- 局部内部类是定义在外部类的局部位置,比如方法中,并且有类名。
-
可以直接访问外部类的所有成员,包含私有的。
-
不能添加访问修饰符,因为它的地位就是一个局部变量。局部变量是不能使用修饰符的。但是可以使用final 修饰,因为局部变量也可以使用final。
-
作用域:紧急在定义它的方法或代码块中。
-
局部内部类---访问-->外部类的成员 [访问方式:直接访问]
-
外部类--访问--->局部内部类的成员
访问方式:创建对象。再访问(必须再作用域内)
- 局部内部类定义位置、 作用域再方法体或者代码块中、 局部内部类本质还是一个类。
- 外部其他类 ---不能访问----->局部内部类(因为 局部内部类地位是一个局部变量)
- 如果外部类和局部内部类的成员重名是,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问。
解释原因:老韩解读:Outer02.this.n1 本质就是外部类的对象,即哪个对象调用了m1,那么Outer02.this就是哪个对象。
- 局部内部类能干嘛??。。。搞不懂。
匿名内部类的使用(超重要!!!!!)
- 其实匿名内部类有名字(老韩说的。)--它的名字是系统jdk底层取的,用一次就没了,所以没类名。
- 基于接口的内部类
package com.Liao_.anonymousInnerClass;
import com.Liao_.test.A;
public class AnonymousInnerClass {
public static void main(String[] args) {
// AnonymousInnerClass test = new AnonymousInnerClass();
// test.cry();
cry();//静态的cry() 方法可以直接调用。
}
public static void cry(){
//基于接口的内部类定义
IA anonyInnerClass = new IA() {
@Override
public void cry() {
System.out.println("在匿名内部类的IA中的cry");
}
};
//基于类的内部类定义
B b1 = new B("jack");//如果没有{}则是创建对象
B b2 = new B("jack"){ //如果构造器需要传参,则会把形参传入给类的构造器
public void methodB(){
System.out.println("在匿名内部类的B类中的methodB");
}
};
b2.methodB();
System.out.println("anonyInnerClass的运行类型" + (anonyInnerClass.getClass()));
anonyInnerClass.cry();
}
}
//接口IA
interface IA {
public void cry();
}
//B类
class B {
public String name;
public B(String name){
this.name = name;
}
public void methodB(){
}
}
- 小细节 内部类的系统给它的命名如果多创建会自增 $1--> $2 --> $3
匿名内部类的使用
- 细节!
编译类型是Person 类,运行类型则是 Outer05$1 。。。。动态绑定机制。如果匿名内部类没有重写Person 的hi( ) 方法,则p.hi(); 方法的调用走继承的流程
匿名内部类甚至可以直接调用 .hi(); 方法。如上图
匿名内部类最佳实践
此代码涉及:1.继承 2.多态 3.动态绑定 4.内部类
package com.Liao_.anonymousInnerClass;
public class InnerClassExercise02 {
public static void main(String[] args) {
CellPhone cellPhone1 = new CellPhone();
cellPhone1.alarmClock(new Bell(){
@Override
public void ring(){
System.out.println("懒猪起床了");
}
});
cellPhone1.alarmClock(new Bell(){
@Override
public void ring(){
System.out.println("小伙伴们上课了");
}
});
}
}
interface Bell{
void ring();
}
class CellPhone {
public void alarmClock(Bell bell){
bell.ring();
}
}
成员内部类
- 成员内部类可以用修饰符(public、protected、默认、private),因为它毕竟是一个成员,成员也能用这些修饰符。
- 外部其他类--访问--->成员内部类 (三种方式)
- 第一种方式 Outer08.Inner08 inner08 = outer08.new Inner08(); (这里的outer08是对象名)
- 第二种方式 在外部类中,编写一个方法,可以返回 Inner08 对象
package com.Liao_.test;
public class test {
public static void main(String[] args) {
OuterClass outerClass = new OuterClass();
//外部类访问成员内部类 第一种方法
OuterClass.InnerClass abc = outerClass.new InnerClass();
//外部类访问成员内部类 第二种方法
OuterClass.InnerClass test = outerClass.getInnerInstance();
// test.innerMethod();
abc.innerMethod();
}
}
class OuterClass {
public String name = "外部类name";
public int age;
private char gender;
//外部类的的私有方法
private void cry(){
InnerClass innerClass = new InnerClass();
//在外部类中的方法可以调用内部类中的私有属性
System.out.println(innerClass.sal);
}
//外部类写一个方法返回内部类的对象。
public InnerClass getInnerInstance(){
return new InnerClass();
}
//成员内部类
class InnerClass{
private int sal;
private String name = "成员内部类name";
public void innerMethod(){
//成员内部类可以访问外部类的私有属性
System.out.println(gender);
cry();//成员内部类可以访问外部类私有方法
//如果成员内部类的成员和外部类成员重名。就会遵守就近原则。
System.out.println(OuterClass.this.name);//外部类name
}
}
}
静态内部类
package com.Liao_.staticInnerClass;
public class Test {
public static void main(String[] args) {
//外部其它类 使用静态内部类。
//(1) 方式一:因为静态内部类,是可以通过类名直接访问
//前提 --是满足访问条件
// A.InnerB innerB = new A.InnerB();
//(2) 方式二:编写一个方法,可以返回静态内部类对象实例。
A a = new A();
//创建静态内部类的对象并调用其方法
a.getInnerBInstance().innerStaticMethod();
}
}
class A {
private String name;
private int Age;
private static double sal=99;
private void outClassMethod(){}
private static void outClassStaticMethod(){}
public InnerB getInnerBInstance(){
return new InnerB();
}
static class InnerB {
public void innerStaticMethod (){
//静态内部类访问外部类的静态属性/方法
System.out.println(sal);
outClassStaticMethod();
// outClassMethod();//访问外部类非静态方法 报错
//静态内部类访问外部类非静态属性 报错
// System.out.println(name);//报错
}
}
}
静态内部类如果和外部类成员重名,可以直接使用(外部类名.成员)去访问外部类重名成员。
因为其是静态内部类,所以可以直接使用 外部类.成员
。
小结:(1)内部类有四种:局部内部类、匿名内部类、成员内部类、静态内部类
(2)重点掌握 匿名内部类
的使用
new 类/接口( 参数列表 ){ };
(3)成员内部类,静态内部类 是放在外部类的成员位置,本质就是一个成员。