Java内部类

内部类

成员内部类

成员内部类可以被4种不同的权限修饰

可以调用外部类的结构;

可以声明为static 的,但不能再使用外部类的非 static 的成员变量;

可以在成员内部类定义属性、方法、构造器等结构;

可以声明为 abstract 类,因此可以被其他的内部类继承;

可以声明为 final 的,表示此类不能被继承;

编译后生成 OuterClass$InnerClass.class 字节码文件(同样适用于局部内部类);

注意

1.非 static 的成员内部类中的成员不能声明为static 的,只有在外部类或static 的成员内部类中才可以声明static成员;

2.外部类访问成员内部类的结构(属性、方法等),需要 "内部类名.成员" 或 "内部类对象.成员" 的方式;

3.成员内部类可以直接使用外部类的所有成员,包括私有的数据(重名的成员另加考虑,如:内部类的定义与外部类相同的属性);

4.当想要在外部类的静态成员部分使用内部类时,可以考虑内部类声明为静态的;

5.内部类与内部类之间不能直接使用成员,但可以在内部类中创建另一个内部类的对象,然后调用相应成员。

class Person {
String name = "小明";
int age;
public static void eat() {
System.out.println("人:吃饭");
}
//静态成员内部类
static class Dog {
String name;
int age;
public void show() {
System.out.println("卡拉是条狗");
eat();
}
}
//非静态成员内部类
class Bird {
String name = "杜鹃";
public Bird() {
}
public void sing() {
System.out.println("我是一只小小鸟");
Person.this.eat();//调用外部类的非静态属性
eat();
System.out.println(age);
}
public void display(String name) {
System.out.println(name);//方法的形参
System.out.println(this.name);//内部类的属性
System.out.println(Person.this.name);//外部类的属性
}
}
}
public class InnerClassTest {
public static void main(String[] args) {
//创建Dog实例(静态的成员内部类):
Person.Dog dog = new Person.Dog();
dog.show();
//创建Bird实例(非静态的成员内部类):
// Person.Bird bird = new Person.Bird();//错误的
Person p = new Person();
Person.Bird bird = p.new Bird();
bird.sing();
System.out.println();
bird.display("黄鹂");
}
}

局部内部类

只能在声明它的方法或代码块中使用,而且是先声明后使用。除此之外的任何地方都不能使用该类。

但是,它的对象可以通过外部方法的返回值返回使用,返回值类型只能是局部内部类的父类或父接口类型。

特点:

1.局部内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件;但是前面会冠以 外部类的类名和$符号,以及数字编号;

2.局部内部类可以使用外部类的成员,包括私有的;

3.局部内部类可以使用外部方法的局部变量,但是必须是 final 的。由局部内部类和局部变量的声明周期不同所致;

4.局部内部类和局部变量地位类似,不能使用4中权限修饰符。

5.局部内部类不能使用 static 修饰,因此不能包含静态变量;

class Person {
String name = "小明";
int age;
// 方法中声明局部内部类
public void method() {
//局部内部类
class AA {
}
}
// 代码块中声明局部内部类
{
//局部内部类
class BB {
}
}
// 构造器中声明局部内部类
public Person() {
//局部内部类
class CC {
}
}
}

匿名内部类

匿名内部类不能定义任何静态成员、方法和类,只能创建匿名内部类的一个实例,一个匿名内部类一定是在 new 的后面,用其隐含实现一个接口或实现一个类。

格式:

new 父类构造器(实参列表) | 实现接口() {
// 匿名内部类的结构体部分
}

特点:

1.匿名内部类必须继承父类或实现接口

2.匿名内部类只能有一个对象

3.匿名内部类对象只能使用多态形式引用

举个🌰:

Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?

匿名的内部类是没名字的内部类。不能extends(继承) 其它类,但一个内部类可以作为一个接口,由另一个内部类实现

静态内部类

  • 静态内部类加载时不会加载外部类
  • 静态内部类可以直接创建实例
  • 类的静态属性只会在第一次加载类的时候初始化
public class House {
public House() {
System.out.println("house constructor");
}
static {
System.out.println("house static block");
}
public static class Home {
public static final Window DALAJIAO = new Window();
public Home() {
System.out.println("home constructor");
}
static {
System.out.println("home static block");
}
}
}

测试:

@Test
public void testStaticInsideClass(){
new House.Home();
}

结果:由结果可以得到,静态内部类可以直接创建实例,并且不会加载外部类。

home static block
home constructor
Process finished with exit code 0

测试:如果在外部类的main方法内创建静态内部类实例肯定会加载外部类。

public class House {
public House() {
System.out.println("house constructor");
}
static {
System.out.println("house static block");
}
public static class Home {
public static final Window DALAJIAO = new Window();
public Home() {
System.out.println("home constructor");
}
static {
System.out.println("home static block");
}
}
public static void main(String[] args) {
new Home();
}
}

结果:

house static block
home static block
home constructor
Process finished with exit code 0
posted @   Lz_蚂蚱  阅读(6)  评论(0编辑  收藏  举报
(评论功能已被禁用)
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起