Java|内部类总结

#Java [字体 ··]

一、什么是内部类?

内部类是在一个类中的类,类的声明可在类中或方法中。

内部类的特点

优点:

  • 内部类可以方便的访问外部类的隐式成员变量
  • 一个类作为内部类是一种很好的信息隐藏,例如静态内部类需要使用 类名.内部类 引出,成员内部类使用 对象.内部类 引出
  • 内部类可以实现单继承的局限性

缺点:

  • 结构复杂

结构复杂体现下内部类的访问、内部类中使用外部类的成员变量等方面。

二、四种内部类

成员内部类

 1public class Person {
 2    String name;
 3    int age;
 4
 5    public Person(String name, int age) {
 6        this.name = name;
 7        this.age = age;
 8    }
 9
10    public void broadcastRepeat(String msg) {
11        Beee b = new Beee(msg);
12        //开始哔哔
13        b.start();
14    }
15
16    // 复读机,重复Person想要说的信息
17    // 普通内部类通过外部类的对象创建, 引用属于对象,每个内部类对象都是不一样的
18    // 成员变量是static是必须使用final修饰
19    public class Beee extends Thread {
20        private String msg;
21
22        public Beee(String msg) {
23            this.msg = msg;
24        }
25
26        @Override
27        public void run() {
28            System.out.println(name);
29            while (true){
30                // 为什么能使用外部类的name,因为在调用构造器时把Person对象传入了进来,通过字节码可以看出来,下面对应着Beee的构造器
31                //INVOKESPECIAL elltor/basic/innerclass/normal/Person$Beee.<init> (Lelltor/basic/innerclass/normal/Person;Ljava/lang/String;)V
32                System.out.println(msg + "  --" + name);
33                try {
34                    Thread.sleep(1000);
35                } catch (InterruptedException e) {
36                    e.printStackTrace();
37                }
38            }
39        }
40    }
41}
42
43
44// test
45public class T {
46    public static void main(String[] args) {
47        Person lisi = new Person("lisi", 18);
48        //lisi.broadcastRepeat("大家好哇~");
49
50        // 通过对象创建普通内部类,然后使用(看上去有些奇怪,因为这是对象持有的类,所以通过对象可以创建,而静态类使用类名.创建)
51        // 注意每个对象的内部类都是不一样的
52        Person.Beee bb = lisi.new Beee("bb create by lisi");
53        bb.start();
54    }
55
56}

静态内部类

 1public class Person4 {
 2    String  name;
 3    int age;
 4
 5    public Person4(String name, int age) {
 6        this.name = name;
 7        this.age = age;
 8    }
 9
10    public void broadcastRepeat(String msg) {
11        Beee b = new Beee(msg);
12        //开始哔哔
13        b.start();
14    }
15
16    // 静态内部类不能使用非静态的变量
17    // 静态内部内能够被其他类使用,而普通内部类只能在定义它类中使用
18    public static class Beee extends Thread {// 复读机,重复Person想要说的信息
19        private String msg;
20
21        public Beee(String msg) {
22            this.msg = msg;
23        }
24
25        @Override
26        public void run() {
27            while (true){
28
29                System.out.println(msg);
30                try {
31                    Thread.sleep(1000);
32                } catch (InterruptedException e) {
33                    e.printStackTrace();
34                }
35            }
36        }
37    }
38}
39
40
41//test
42public class T {
43    public static void main(String[] args) {
44        // 1
45        Person4 p = new Person4("lisi",19);
46        p.broadcastRepeat("hello everyone~ ");
47
48        // 2
49        Person4.Beee bee = new Person4.Beee("在Person4外使用");
50        bee.start();
51    }
52}

局部内部类

 1public class Person2 {
 2    String name;
 3    int age;
 4
 5    public Person2(String name, int age) {
 6        this.name = name;
 7        this.age = age;
 8    }
 9
10    public void broadcastRepeat(String msg) {
11        // 不能使用publi或private修饰,可以使用final修饰
12        // 该类对于完结来说完全隐藏,每调用此方法创建一次且使用一次
13        class Beee extends Thread {// 复读机,重复Person想要说的信息
14            private String msg;
15
16            public Beee(String msg) {
17                this.msg = msg;
18            }
19
20            @Override
21            public void run() {
22                while (true){
23                    System.out.println(msg);
24                    try {
25                        Thread.sleep(1000);
26                    } catch (InterruptedException e) {
27                        e.printStackTrace();
28                    }
29                }
30            }
31        }
32
33        Beee b = new Beee(msg);
34        //开始哔哔
35        b.start();
36    }
37}
38
39// test
40public class T {
41    public static void main(String[] args) {
42        Person2 p = new Person2("lisi",18);
43        p.broadcastRepeat("大家好哇~");
44    }
45}

匿名内部类

 1public class Person3 {
 2    String name;
 3    int age;
 4
 5    public Person3(String name, int age) {
 6        this.name = name;
 7        this.age = age;
 8    }
 9
10    // 匿名内部类1,匿名生成一个子类覆盖父类的方法
11    public void broadcastRepeat(String msg) {
12        new Thread() {
13            @Override
14            public void run() {
15                while (true) {
16                    System.out.println(msg);
17                    try {
18                        Thread.sleep(1000);
19                    } catch (InterruptedException e) {
20                        e.printStackTrace();
21                    }
22                }
23            }
24        }.start();
25    }
26
27    // 匿名内部类2,匿名创建接口对象
28    public void broadcastRepeat2(String msg) {
29
30        Runnable run = new Runnable() {
31            @Override
32            public void run() {
33                while (true) {
34                    System.out.println(msg);
35                    try {
36                        Thread.sleep(1000);
37                    } catch (InterruptedException e) {
38                        e.printStackTrace();
39                    }
40                }
41            }
42        };
43
44        new Thread(run).start();
45    }
46}
47
48
49// test
50public class T {
51    public static void main(String[] args) {
52        Person3 p = new Person3("lisi",18);
53        //p.broadcastRepeat("hello~");
54        p.broadcastRepeat2("hello2~");
55    }
56}

内部类的使用

在 JDK 的集合框架中大量使用到内部类

并不只有内部类,接口也可以定义在一个接口里。

Map 中定义的 Entry 接口

 1public interface Map<K,V>{
 2    interface Entry<K,V> {
 3
 4        K getKey();
 5
 6        V getValue();
 7
 8        V setValue(V value);
 9
10        boolean equals(Object o);
11    }
12}

HashMap 中的内部类

image.png

image.png

构建者模式(Builder)

https://zhuanlan.zhihu.com/p/58093669

 1public class Computer {
 2    private final String cpu;//必须
 3    private final String ram;//必须
 4    private final int usbCount;//可选
 5    private final String keyboard;//可选
 6    private final String display;//可选
 7
 8    private Computer(Builder builder){
 9        this.cpu=builder.cpu;
10        this.ram=builder.ram;
11        this.usbCount=builder.usbCount;
12        this.keyboard=builder.keyboard;
13        this.display=builder.display;
14    }
15    public static class Builder{
16        private String cpu;//必须
17        private String ram;//必须
18        private int usbCount;//可选
19        private String keyboard;//可选
20        private String display;//可选
21
22        public Builder(String cup,String ram){
23            this.cpu=cup;
24            this.ram=ram;
25        }
26
27        public Builder setUsbCount(int usbCount) {
28            this.usbCount = usbCount;
29            return this;
30        }
31        public Builder setKeyboard(String keyboard) {
32            this.keyboard = keyboard;
33            return this;
34        }
35        public Builder setDisplay(String display) {
36            this.display = display;
37            return this;
38        }
39        public Computer build(){
40            return new Computer(this);
41        }
42    }
43  //省略getter方法
44}


博客没有评论系统,可以通过 邮件 评论和交流。 Top↑