内部类*

成员内部类

  1. 内部类可以使用public private protected default static修饰
  2. java源文件中仅包含一个外部类和一个内部类时,编译会生成两个class文件:外部类.class、外部类$内部类.class
  3. 外部类的静态方法不能访问非静态内部类;静态内部类无法访问外部类非静态成员

非静态内部类

  无static修饰符修饰的非静态内部类,只能包含非静态成员

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class 外部类 {
public 外部类(){
// 外部类的构造器,在构造器中调用内部类的methods方法
内部类 内部类对象 = new 内部类();
内部类对象.methods();
}
public static void main(String[] args) {
// 外部类的main方法
}
// 非静态内部类内无法创建静态成员
public class 内部类{
public void methods(){
// 非静态内部类的实例方法
}
public 内部类(){
// 内部类的构造器
}
}
}

  当非静态内部类的方法中访问某个变量时,系统优先寻找局部变量,不存在则寻找内部类中的成员变量,依然不存在继续寻找类中的成员变量
  如果内部类的局部变量、内部类成员变量和成员变量同名,可以通过this、外部类类名.this来区分内部类成员变量和外部类成员变量

1
2
3
4
5
6
7
8
9
10
11
12
public class 外部类{
private String prop = "成员变量";
public class 内部类{
private String prop = "内部类成员变量";
public void test(){
String prop = "局部变量";
System.out,println(prop); // 局部变量
System.out,println(this.prop); // 内部类成员变量
System.out,println(外部类.this.prop); // 外部类成员变量
}
}
}

  在外部类内使用非静态内部类的实例方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class 外部类 {
public static void main(String[] args) {
// 外部类的main方法
}

public void test(){
内部类 内部类对象 = new 内部类(); // 通过对象调用
内部类对象.methods();
}
public class 内部类{
public void methods(){

}
}
}


  在外部类外使用非静态内部类的实例方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class 外部类 {
public static void main(String[] args) {

}
public class 内部类{
public void methods(){
System.out.println("调用了");
}
}
}

class 调用外部类的内部类{
public static void main(String[] args) {
// 外部类名.内部类名 变量名 = new 外部类名().new 内部类名();
外部类.内部类 内部类对象 = new 外部类().new 内部类();
内部类对象.methods();
}
}

静态内部类

  用static修饰的类叫内部类;内部类可以包含静态和非静态成员
  因为可以包含静态成员,所以静态内部类可以执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class 外部类2 {
private String prop = "成员变量";
public 外部类2(){
// 外部类的构造器
}
public static void main(String[] args) {
内部类.main(new String[]{}); // 调用静态内部类的静态方法
new 内部类().test(); // 调用静态内部类的实例方法
}
public static class 内部类{
public static void mian(String[] args){
// 内部类的静态方法
}
public void test(){
// 内部类的实例方法
}
public 内部类(){
// 内部类的构造器
}
}
}

  在外部类内使用静态内部类中的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class 外部类2 {
public static void main(String[] args) {
内部类.main(new String[]{}); // 调用静态内部类的静态方法
new 内部类().test(); // 调用静态内部类的实例方法
}
public static class 内部类{
public static void main(String[] args){
// 内部类的静态方法
System.out.println("静态方法");
}
public void test(){
// 内部类的实例方法
System.out.println("实例方法");
}
}
}

  在外部类外使用静态内部类中的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class 外部类2 {
public static void main(String[] args) {

}
public static class 内部类{
public static void main(String[] args){
// 内部类的静态方法
System.out.println("静态方法");
}
public void test(){
// 内部类的实例方法
System.out.println("实例方法");
}
}
}

class 外部类外{
public static void main(String[] args) {
外部类2.内部类.main(new String[]{}); // 在外部类外调用静态内部类的静态方法
new 外部类2.内部类().test(); // 在外部类外调用静态内部类的实例方法
}
}

局部内部类

  1. 局部内部类不能使用访问控制符和修饰符
  2. 所有的局部内部类成员都不能使用访问控制修饰符
  3. java源文件中仅包含一个外部类和一个局部内部类时,编译会生成两个class文件:外部类.class、外部类$1内部类.class
1
2
3
4
5
6
7
8
9
10
11
public class public_test {
public static void main(String[] args) {
class 局部内部类 {
public void main() {
System.out.println("main");
}
}
局部内部类 局部内部类对象 = new 局部内部类();
局部内部类对象.main();
}
}

  局部内部类,食之无味,弃之可惜,就是个垃圾,没吊用

匿名内部类

  1. 匿名内部类不能是抽象类
  2. 匿名内部类必须继承一个父类,或实现一个接口,但最多只能继承或实现一个
  3. 匿名内部类不能定义构造器,但可以定义初始化块,通过实例初始化块完成构造器的任务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class public_test {
public void test(接口 j){
System.out.println(j.getName());
}
public static void main(String[] args) {
public_test pt = new public_test();
// 继承了“接口”
pt.test(new 接口(){
@Override // 重写接口内的getName方法
public String getName(){
return "测试";
}
});
}
}

interface 接口{
String getName();
}

可改写为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class public_test {
public void test(接口 j){
System.out.println(j.getName());
}
public static void main(String[] args) {
public_test pt = new public_test();
class 类 implements 接口{
@Override
public String getName(){
return "测试";
}
}
pt.test(new 类());
}
}
interface 接口{
String getName();
}

还可改写为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class public_test {
public void test(抽象类 j){
System.out.println(j.getName());
}
public static void main(String[] args) {
public_test pt = new public_test();
pt.test(new 抽象类(){
@Override
public String getName(){
return "测试";
}
});
}
}
abstract class 抽象类{
public abstract String getName();
}