内部类和代码块
内部类
类中的五大成员:属性,方法,构造器,代码块,内部类
源码中会有大量内部类
内部类的分类:
定义在外部类的局部位置上(比如方法内):
- 局部内部类(有类名)
- 匿名内部类(没有类名,重点!)
定义在外部类的成员位置上:
- 成员内部类(没用static修饰)
- 静态内部类(用static)
局部内部类:
- 在外部类的局部位置,通常在方法(或代码块)里
- 可以访问到外部类的所有成员,包括私有的
- 不能添加访问修饰符,但是可以用final修饰
- 作用域:仅仅在定义它的方法里
- 外部类在方法中又可以创建局部类的对象,任何调用方法
- 本质上还是一个类,类有的它也有
- 当外部类和内部类属性或者方法重复了,可以通过外部类.this.方法(属性)
匿名内部类:
为什么要有匿名内部类:
当我们有一个父类或者接口,有一个子类要去继承或者实现他们,但这个子类我们只用一次,那么创建这个子类就显得麻烦,所以就有了匿名内部类
public class AnonymousClass {
public static void main(String[] args) {
A a=new A() { //这个匿名内部类的编译类型:A
@Override //运行类型:匿名内部类
public void a() {//在这个底层其实创建了匿名内部类后,马上就创建了内部类的实例,并将他返回给a
System.out.println("你好");
}
};
a.a();
}
}
interface A{
void a();
}
基础概念:
- 本质是一个类,内部类,该类没有名字,同时还是一个对象
- 基础语法:new 类或接口(参数列表)
- A a=new A() {重写的抽象方法},A为接口,此时编译类型:A,运行类型:匿名内部类
- 在这个底层其实创建了匿名内部类后,马上就创建了内部类的实例,并将他返回给a
- 并不是没有名字,其实用getClass可以获取到这个类,但是这个实例一用完就会销毁
- 匿名内部类无法向下转型(拿不到),所以调用不到不同于父类的特有方法
细节(和局部内部类一样):
- 同样是内部类,所以也可以访问到外部类的所有成员
- 不能添加修饰符,因为它本身地位就是一个局部变量
- 作用域:定义它的方法或代码块里
- 外部其他类不能实例化这个类,因为它就实例化一次就销毁了
- 当外部类和内部类属性或者方法重复了,调用会有就近原则,可以通过外部类.this.方法(属性)调用内部类里的方法属性
应用场景:
- 跟多态传实参连用
interface I{
void a1();
}
class test2{
public static void main(String[] args) {
method(new I() {
@Override
public void a1() {
System.out.println("使用匿名类实现多态传参");
}
});
}
public static void method(I i){
i.a1();
}
}
成员内部类:
- 可以访问到内部类的所有成员,包括私有的
- 可以添加任何权限修饰符,因为它本身就是一个成员
- 可以访问到外部类的所有成员,包括私有的
- 外部类访问到内部类,创建内部类对象
- 外部其他类访问成员内部类,不能直接实例化,而要先调用再实例化
- 当外部类和内部类属性或者方法重复了,调用会有就近原则,可以通过外部类.this.方法(属性)调用内部类里的方法属性
外部其他类访问成员内部类:

静态内部类:
- 放在外部类的成员位置
- 使用static修饰
- 可以访问到外部类的所有静态成员,,但不能访问到非静态类的
- 可以是任意权限修饰符
- 作用域,同其他成员,为整个类
- 外部类访问静态内部类,创建对象访问
- 外部的其他类访问,通过外部类名.内部类名调用
总结:
-
内部类分为局部内部类:局部内部类,匿名内部类
-
局部内部类:
- 定义在方法和代码块中
- 能访问到外部类的所有属性和方法
- 不能添加修饰符
- 作用域在方法或者代码块
- 本质还是一个类,类该有的它都有
- 外部类向访问它,就必须在创建它的对象,在调用
- 当内部类和外部类属性或者方法有重复名,就近原则
-
匿名内部类
-
满足局部内部类
-
出现的原因,是解决了继承和实现如果只实例化次数很少,而需要去创建子类,很麻烦
-
基础语法:new 接口(父类){重写的方法};
-
编译类型是接口或者父类,但是运行类型还是匿名内部类
-
应用可以跟多态的实参一起用
-
-
-
内部类还有成员内部类:成员内部类,静态成员内部类
-
成员内部类
-
是一个成员
-
可以访问到外部类的所有属性和方法
-
既然是一个成员,那肯定可以有权限修饰符
-
作用域:整个类
-
外部类访问它,必须得创建实例
-
-
静态成员内部类:
- 除了调用外部类属性时,只能调用静态的
- 外部的其他类调用这个类,用外部类.这个类的形式,把这个类当成类成员就行
-
代码块:
介绍:
代码块又叫初始化块,属于类的成员,类似于方法,将逻辑语句封装到方法体里,不能通过对象等显性调用,而是在加载类时,或创建对象时隐形创建
基础语法:【修饰符】{
代码
}
修饰符只能是static
有什么用:
对构造器的补充,当我们的类里几个构造器都有相同的代码,显得冗余,这个时候就可以使用代码块,代码块,会在创建对象时,先于构造器里的内容创建
public class Code1 {
public static void main(String[] args) {
A a = new A(20);
A a1 = new A(20,"lc");
}
}
class A{
{
System.out.println("开始了");
}
A(int a){
System.out.println("我的"+a+"岁");
}
A(int a,String name){
System.out.println(name+"的"+a+"岁");
}
}
细节:
- 被Static修饰的代码块,叫静态代码块,它随着类的加载而产生,并且只执行一次,普通代码块每创建一个对象执行一次
- 类在什么时候会被加载(重要)
- 创建对象实例时
- 创建子类对象实例,父类也会被加载
- 使用类的静态成员时
- 普通代码块在创建对象实例时,会被隐式的调用
浙公网安备 33010602011771号