javaSE复习之——面向对象_内部类

内部类的概述

  • 内部类就是在一个类中定义的另一个类。
    • ps:刚开始学java对于内部类用到的着实不多,但随着编程能力的提高,我们会领悟到它魅力的所在

内部类的分类

成员内部类

它定义在一个的内部

局部内部类

它定义在一个方法或者一个作用域内部,它的访问仅限于方法内或者该作用域内

注意事项:

局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的

匿名内部类

匿名内部类应该是平时我们编写代码时用得最多的,在编写事件监听的代码时使用匿名内部类不但方便,而且使代码更加容易维护

例如:为按钮设置一个监听器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub

}
}```

#### `静态`内部类
它是定义在另一个类里面的类,只不过在类的前面多了一个关键字static


# 内部类的面试题之 —— `内部类`能不能访问`外部类`成员变量?
- 答(成员内部类):
`内部类`可以访问`外部类`的成员变量,因为编译器底层在创建`成员内部类`时,为成员内部类加上了指向外部类的引用

示例:
外部类.this.成员变量
外部类.this.成员方法
1
2
3
- ps:虽然内部类访问外部类可以随心所欲,但是外部类想要访问内部类就需要创建内部类实例然后利用对它的引用进行访问了
- 例子:

class Circle {
private double radius = 0;

public Circle(double radius) {
    this.radius = radius;
    getDrawInstance().drawSahpe();
    //必须先创建成员内部类的对象,再进行访问
}
 
private Draw getDrawInstance() {
    return new Draw();
}
 
class Draw {     //内部类
    public void drawSahpe() {
        System.out.println(radius);
        //外部类的private成员
    }
}

}

1
2
3

# `匿名内部类`访问外部类成员底层实现原理:
> 我们用一段代码来举例:

public class Test {
public static void main(String[] args) {

}
 
public void test() {
    final int a = 10;
    new Thread(){
        public void run() {
            System.out.println(a);
        };
    }.start();
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
> 当test方法调用,系统会给内部类自动加上构造器`(这也就是为什么匿名内部类不能有构造方法的原因)`,这个构造器含有两个参数,一个指向外部类对象的引用,一个是int类型变量,这个int类型变量就是外部类中那个int变量的拷贝,它的值也就是10,同理如果是一个引用数据类型的话,那就是一个在堆内存中的地址值。`这样就解决了生命周期的问题`
>
> `但是还有一个数据不一致的问题`,如果内部类或者外部类修改了这个变量的值,那么对方是不可能知道的,所以造成了数据不一致的问题。
>
> 数据不一致问题的`解决方法`就是直接给变量修饰一个final,这就是为什么匿名内部类访问外部类中的变量时,这个变量一定要final修饰的原因

- 在jdk8之前,局部内部类访问外部类成员变量,那么外部类的那个变量就需要用`final`修饰
- jdk8新特性
> 局部内部类与匿名内部类访问外部类成员变量,外部类那个变量`不需要`final修饰了,但其实只是个“语法糖”,只要有对这个成员变量修改的操作,还是会强制要求final修饰的。
>





# 匿名内部类
- 格式:

//如果是类那么就代表继承这个类,是抽象类那么就是实现这个抽象方法
new 类名或者抽象类名() {

}.方法名()
//.方法名()可有无,只是加上可以直接调用匿名内部类中的方法

```

  • 解释:

    可以吧new 到 } 的代码看作创建的一个子类对象实例,所以后面可以.方法名调用

  • 好处:

    可以不用声明一个类了,而且把代码都集成到了一起,可以使代码更加简洁。

  • 注意事项:

    1、匿名内部类只针对重写一个方法使用,如果要一次性重写多个方法的话不使用,因为调用一次就要创建一次对象,这样就没必要使用匿名内部类了,如果要多次使用则重新定义类

    2、匿名内部类可以当作参数传递,本质是把匿名内部类看作一个子类对象。

    3、匿名内部类中不能定义构造函数。

    4、使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,只能继承一个类或者实现一个接口。

    5、匿名内部类中不能存在任何的静态成员变量和静态方法。

    6、匿名内部类属于局部内部类,所以局部内部类所有限制都在匿名内部类上生效

    7、匿名内部类不能是抽象的,它必须实现继承的类或者接口中的抽象方法

链式编程:

  • 特点:

    调用方法后还能调用方法,也就是说调用第一个方法之后返回的是一个对象。