内部类

 

1.内部类概述

如果一个类存在的意义就是为指定的另一个类,可以把这个类放入另一个类的内部。 就是把类定义在类的内部的情况就可以形成内部类的形式。 A类中又定义了B类,B类就是内部类,B类可以当做A类的一个成员看待:

 

class A { //我是外部类A
    class B { // 我是内部类B
        // 内部类B只为A类服务,可以看做是外部类A类的一个特殊成员
    }
}

2.特点

 1.内部类可以直接访问外部类中的成员,包括私有成员
2.外部类要访问内部类的成员,必须要建立内部类的对象
3.在成员位置的内部类是成员内部类
4.在局部位置的内部类是局部内部类

3.练习:内部类入门案例

/*测试内部类的入门案例*/
public class demo01 {
    public static void main(String[] args) {
        //3.创建内部类对象,使用内部类的资源
        /* 外部类名.内部类名  对象名 = 外部类对象.内部类对象 */
        Outer.Inner oi = new Outer().new Inner();
        oi.add();
        System.out.println(oi.num);
​
​
        //4.调用外部类的方法 --- 这样是创建了一个外部类的匿名对象,只使用一次
        new Outer().find();
​
    }
​
}
​
//1.创建一个外部类Outer
class Outer{
​
    //1.1 创建外部类的成员变量
    String name;
    private int age;
​
    //1.2创建外部类的成员方法
    public void find(){
        System.out.println("Outer...find()");
        //6.测试外部类如何使用内部类的资源
        /* 外部类如果想用内部类的资源,必须先创建内部类对象
        * 通过内部类对象调用内部类的资源 */
        Inner inner = new Inner();
        inner.add();
        System.out.println(inner.num);
    }
​
    //2.创建一个内部类Inner --- 类的特殊成员
    class  Inner{
        //2.1 定义内部类的成员变量
        int num = 1;
​
        //2.2 定义内部类的成员方法
        public void add(){
            System.out.println("Inner...add()");
​
            //5. 测试内部类是否可以使用外部类的资源
            /* 内部类可以直接使用外部类的资源,包括私有成员 */
            System.out.println(name);
            System.out.println(age);
​
        }
​
    }
​
}

4.成员内部

4.1被private修饰
/**本类用来测试成员内部类被private修饰*/
public class demo02 {
    public static void main(String[] args) {
​
        //3.创建内部类对象,使用内部类资源
        /* 么使用内部类Inner2的资源? */
//        Outer2.Inner2 oi = new Outer2().new Inner2();
//        oi.eat();
/* 如果Inner2被private修饰,无法直接创建对象该怎么办? */
        //6.创建外部类对象,间接访问私有内部类资源
        new Outer2().getInner2Eat();
​
        /*
        * 一旦私有化内部类,则想要再使用内部类的资源
        * 就要从之前的一步到位:外部类名.内部类名  对象名 = 外部类对象.内部类对象
        * 变成现在的两步:
        *       ①提供外部类公共的方法,在方法内部创建Inner2内部类对象,调用内部类方法
        *       ②创建外部类对象,间接访问私有内部类资源
        * */
​
    }
}
​
//1.创建外部类
class Outer2{
    //5.提供外部类公共的方法,在方法内部创建Inner2内部类对象,调用内部类方法
    public void getInner2Eat(){
        Inner2 inner2 = new Inner2();//外部类可以访问内部类的私有成员
        inner2.eat();
    }
​
        //2.创建内部类
        /* 成员内部类的位置:类里方法外 */
        //4.成员内部类,被private修饰私有化,无法被外界访问
        private class Inner2{
​
            //2.1定义成员方法
            public void eat(){
                System.out.println("Inner2...eat()");
            }
        }
​
}
​
总结:
成员内部类被private修饰之后,无法被外界直接创建对象使用
所以可以创建外部类对象,通过外部类对象间接访问内部类的资源

 

4.2 被static修饰
/**本类用来测试成员内部类被static修饰*/
public class demo03 {
    public static void main(String[] args) {
        /**如何访问内部类的show()?*/
        //3.创建内部类对象,得到内部类资源
        /*//方式一:按照之前的方式,创建内部类对象调用
        Outer3.Inner3 oi = new Outer3().new Inner3();
        oi.drink();
​
        //方式二:创建匿名内部类对象访问
        new Outer3().new Inner3().drink();
*/
        /**现象:当内部类被static修饰以后,new Outer3()报错*/
        //5.用static修饰内部类以后,上面的创建语句报错,要注释掉!
        //通过外部类的类名创建内部类对象
        Outer3.Inner3 oi = new Outer3.Inner3();//注意这里!!!不是new Outer3().new Inner3()
        oi.drink();
​
        //6.匿名内部类对象调用drink()
        new Outer3.Inner3().drink();
​
        //8.访问静态内部类中的静态资源---链式加载
        Outer3.Inner3.drink2();
​
    }
}
​
//1.创建外部类Outer3
class Outer3{
​
    //2.创建成员内部类Inner3
    //4.内部类被static修饰--并不常用!浪费内存!
    static class Inner3{
        //2.1 定义成员内部类中普通的成员方法
        public void drink(){
            System.out.println("Inner3...drink()");
        }
​
        //7.定义成员内部类的静态成员方法
        static public void drink2(){
            System.out.println("Inner3...drink2");
        }
    }
​
}
总结:
静态资源访问时不需要创建对象,可以通过类名直接访问
访问静态类中的静态资源可以通过“...”链式加载的方式访问

5.局部内部类

/**本类用来测试局部内部类*/
public class demo05 {
    public static void main(String[] args) {
        /*
        * 如何使用内部类的资源呢?
        * 注意:直接调用外部类的show()是无法触动内部类功能的
        * 需要在外部类中创建内部类对象并且进行调用,才能触发内部类的功能
        * */
        //5.创建外部类对象调用show()
 
        //7.当在外部类show()中创建局部内部类对象并且进行功能调用后,内部类的功能才能被调用
        new Outer4().show();
    }
}
​
//1. 创建外部类
class Outer4{
​
    //2.创建外部类的成员方法
    public void show(){
        //3.创建局部内部类Inner4 --- 不太常用!!!
        /*位置:局部内部类的位置在方法里*/
        class Inner4{
            //4.创建局部内部类的普通属性与方法
            String name;
            int age;
            public void eat(){
                System.out.println("Inner4...eat()");
            }
        }
​
        /*如何使用局部内部类的资源?*/
        //6.在show()里创建内部类对象
        Inner4 inner4 = new Inner4();
        inner4.eat();
        System.out.println("==========");
        System.out.println(inner4.name);
        System.out.println(inner4.age);
​
    }
    
}

6.匿名内部类

/*本类用于测试匿名内部类,没有名字,通常结合着匿名对象一起使用*/
public class demo06 {
​
    public static void main(String[] args) {
        /* 接口可以创建对象吗? 不可以!!!*/
        //new Inner1();//接口不能创建对象
        //3.new Inner1()匿名对象
        //以前我们创建接口,接口不能实例化
        //所以我们创建接口实现类+重写接口中的抽象方法+创建实现类对象+调用方法
        /*  就相当于创建了一个接口的实现类+重写接口中的所有抽象方法 */
        new Inner1(){//3.1接口的实现类
​
            @Override
            public void save() {//3.2重写接口中的抽象方法1
                System.out.println("我是Inner1中的save()");
            }
​
            @Override//3.2重写接口中的抽象方法2
            public void get() {
                System.out.println("我是Inner1中的get()");
            }
        }.get();//3.3触发指定的重写后的方法,只能调用一个,并且只能调用一次
        /*  注意!!!匿名对象只使用一次,而且一次只能干一件事!!! *///5.new Inner2()匿名对象,相当于创建了抽象类的普通子类
        /* 匿名内部类实现的方法都是抽象方法,注意是所有抽象方法 */
        new Inner2() {
            @Override
            public void drink() {
                System.out.println("我是Inner2抽象类的drink()");
            }
        }.drink();
​
​
        //7.普通类的匿名对象,不会强制要求产生匿名内部类的重写方法
        //如果使用对象,只需要干一件事---可以直接创建匿名对象,简单又方便
        new Inner3().power();
        //如果想使用同一个对象来干很多件事情,必须要给对象起名字
        Inner3 inner3 = new Inner3();
        inner3.power();
        inner3.study();
    }
}
​
​
//1.创建接口
interface Inner1{
    //2.定义接口中的抽象方法
    void save();
    void get();
}
​
//4.创建抽象类
abstract  class Inner2{
    public void play(){
        System.out.println("我是Inner2抽象类中的普通方法play()");
    }
    abstract public void drink();
}
​
//6.创建普通类Inner3
class Inner3{
    public void power(){
        System.out.println("我是Inner3普通类中的power()");
    }
​
    public void study(){
        System.out.println("我是Inner3普通类中的study()");
    }
}

总结:
匿名内部类属于局部内部类,而且是没有名字的局部内部类,通常和匿名对象一起使用

 

posted @ 2021-10-31 16:13  wKingy  阅读(58)  评论(0编辑  收藏  举报