栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java学习笔记——内部类

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java学习笔记——内部类

什么是内部类

一个类里面又完整地嵌套了另一个类结构。

类的五大成员

成员属性、成员方法、构造器、代码块、内部类

内部类的特点

内部类的最大特点就是可以直接访问私有属性

内部类的分类
  • 定义在外部类局部位置上(比如方法内)
局部内部类(有类名)
  1. 通常定义在外部类的局部位置,通常在方法/代码块
  2. 不能加修饰符
  3. 能加final

    加了final之后其他类不能继承它
  4. 作用域
    仅仅在定义它的方法或者代码块中
  5. 内部类如何访问外部类:内部类可以直接访问外部类的所有成员,包含私有的
class OuterClass {

    private int n1 = 1;
    private void m(){};
    public void out(){
        // 局部内部类
        // 定义在外部类的方法中,有类名
        // 不能添加修饰符,但是可以用final修饰
        final class innerClass1 {
            public void print(){
                // 内部类可以访问外部类的所有成员,包括私有的
                System.out.println("n1=" + n1);
            }
        }
    }
}
  1. 外部类如何访问内部类:在外部类的方法中,可以创建内部类对象,然后调用
public class InnerClass01 {
    public static void main(String[] args) {
        OuterClass outerClass = new OuterClass();
        System.out.println("==============我即将调用OuterClass类的out方法==============");
        outerClass.out();
    }
}

// 外部类
class OuterClass {

    private int n1 = 1;

    private void m1() {
        System.out.println("我是OuterClass类的m1()方法");
    }

    public void out() {
        // 局部内部类
        // 定义在外部类的方法中,有类名
        // 不能添加修饰符,但是可以用final修饰
        final class Inner1 {
            public void print() {
                System.out.println("我是内部类Inner1的print方法");
                // 内部类可以访问外部类的所有成员,包括私有的
                System.out.println("n1=" + n1);
                // 调用了外部类的方法
                m1();
            }
        }

        // 在OuterClass类的out()创建Inner1类
        Inner1 inner = new Inner1();
        // 在外部类调用内部类的方法
        System.out.println("==============我即将调用内部类的print方法==============");
        inner.print();
    }
}

结果:
我即将调用OuterClass类的out方法
我即将调用内部类的print方法
我是内部类Inner1的print方法
n1=1
我是OuterClass类的m1()方法

  1. 如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,使用外部类名.this.成员名去访问
final class Inner1 {
            private int n1 = 2;
            public void print() {
                System.out.println("我是内部类Inner1的print方法");
                // 内部类可以访问外部类的所有成员,包括私有的
                System.out.println("n1=" + n1);
                // 调用了外部类的方法
                m1();
                System.out.println(n1); // 访问内部类的n1 = 2
                System.out.println(OuterClass.this.n1); // 访问外部类的n1 = 1
            }
        }
匿名内部类(没有类名,重点)
  1. 本质是类
  2. 内部类
  3. 没有名字
  4. 同时也是一个对象
  5. 编译类型是写在左边的类
  6. 运行类型是匿名内部类
    适用场景:这个类只用一次,后面不再使用,不想创建对象,这样可以简化开发。例如:当做实参直接传递
    ***注意:***匿名内部类只能适用一次,但是指向该类的对象可以多次使用
基于接口的匿名内部类
package annoy_;

public class Annoy {
    public static void main(String[] args) {
        B b = new B();
        b.method();
    }
}

interface IA {
    public void cry();
}

class B {
    public void method() {
//         创建匿名能内部类
//         实质是
//            class B implements IA {
//                @Override
//                public void cry() {
//                    System.out.println("老虎嘤嘤嘤...");
//                }
//            }

        IA tiger = new IA() {
            @Override
            public void cry() {
                System.out.println("老虎嘤嘤嘤...");
            }
        };
        // 对象可以多次使用
        tiger.cry();
        tiger.cry();
        tiger.cry();
        // 在jdk的底层,在创建匿名内部类时给了匿名内部类一个名字class annoy_.B$1,并且立刻创建了一个实例
        System.out.println(tiger.getClass());
    }
}
基于类的匿名内部类
// 此时底层解读为
//        class B extends Father {
//            
//        }
// 这里的阿爹,阿往 会传给Father的构造器,不可以重写构造器
Father father1 = new Father("阿爹") {
 };
Father father2 = new Father("阿往");
        System.out.println(father1.getClass());
        System.out.println(father2.getClass());
    }
 Father father1 = new Father("阿爹") {
 };
 Father father2 = new Father("阿往");
          System.out.println(father1.getClass());
        System.out.println(father2.getClass());

结果:
class annoy_.B$2
class annoy_.Father

匿名内部类调用方法


7. 匿名内部类可以直接访问外部类的所有成员,包括私有的
8. 不能添加访问修饰符(它相当于一个局部变量)
9. 作用域:仅仅在定义它的方法或者代码块中
10. 如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,使用外部类名.this.成员名去访问

应用场景实践:当做实参直接传递
package annoy_;

public class AnnoyDemo {
    public static void main(String[] args) {
        f1(new IB() {
            @Override
            public void show() {
                System.out.println("hello");
            }
        });
    }
    // 静态方法,形参是接口类型
    public static void f1 ( IB ib){
        ib.show();
    }
}

interface IB {
    void show();
}
// 传统方法: 写一个类来实现IB,再new一个对象
  • 定义在外部类的成员位置上
成员内部类(没用static修饰)
  1. 没有写在方法中
  2. 可以加修饰符,因为它的地位是一个成员
  3. 作用域:和其他成员一样,为整个类
  4. 成员内部类访问外部类:直接访问
  5. 外部类访问成员内部类:创建对象再访问
  6. 外部其他类访问成员内部类:
    6.1 用外部类的对象new内部类的实例Father.Son son = new Father().new Son();
    6.2 在外部类中写一个方法,返回内部类的对象
静态内部类(用static修饰)

在成员内部类的基础上加了static

  1. 可以访问外部类的所有静态成员,但是不能直接访问非静态成员


2. 可以加修饰符
3. 作用域:为整个类体
4. 静态内部类访问外部类:直接访问所有静态属性
5. 外部类访问静态内部类:创建对象,再访问
6. 外部其他类访问静态内部类:
6.1 在满足访问权限的情况下,外部类.静态内部类,私有情况下;
6.2 编写方法,返回静态内部类的实例

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/353701.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号