第7章 面向对象基础-下(内部类)

7.6 内部类(了解)

7.6.1 概述

1、什么是内部类?

将一个类A定义在另一个类B里面,里面的那个类A就称为内部类 ,B则称为外部类

2、为什么要声明内部类呢?

总的来说,遵循高内聚低耦合的面向对象开发总原则。便于代码维护和扩展。

具体来说,当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,不在其他地方单独使用,那么整个内部的完整结构最好使用内部类。而且内部类因为在外部类的里面,因此可以直接访问外部类的私有成员。

3、内部类都有哪些形式?

根据内部类声明的位置(如同变量的分类),我们可以分为:

(1)成员内部类:

  • 静态成员内部类

  • 非静态成员内部类

(2)局部内部类

  • 有名字的局部内部类

  • 匿名的内部类

7.6.2 成员内部类

如果成员内部类中不使用外部类的非静态成员,那么通常将内部类声明为静态内部类,否则声明为非静态内部类。

语法格式:

【修饰符】 class 外部类{

【其他修饰符】 【static】 class 内部类{

}

}

1、静态内部类

有static修饰的成员内部类叫做静态内部类。它的特点:

  • 和其他类一样,它只是定义在外部类中的另一个完整的类结构

    • 可以继承自己的想要继承的父类,实现自己想要实现的父接口们,和外部类的父类和父接口无关

    • 可以在静态内部类中声明属性、方法、构造器等结构,包括静态成员

    • 可以使用abstract修饰,因此它也可以被其他类继承

    • 可以使用final修饰,表示不能被继承

    • 编译后有自己的独立的字节码文件,只不过在内部类名前面冠以外部类名和$符号。

  • 和外部类不同的是,它可以允许四种权限修饰符:public,protected,缺省,private

    • 外部类只允许public或缺省的
  • 可以在静态内部类中使用外部类的静态成员

    • 在静态内部类中不能使用外部类的非静态成员哦

    • 如果在内部类中有变量与外部类的静态成员变量同名,可以使用"外部类名."进行区别

  • 在外部类的外面不需要通过外部类的对象就可以创建静态内部类的对象(通常应该避免这样使用)

2、非静态成员内部类

没有static修饰的成员内部类叫做非静态内部类。非静态内部类的特点:

  • 和其他类一样,它只是定义在外部类中的另一个完整的类结构

    • 可以继承自己的想要继承的父类,实现自己想要实现的父接口们,和外部类的父类和父接口无关

    • 可以在非静态内部类中声明属性、方法、构造器等结构,但是不允许声明静态成员 ,但是可以继承 父类的静态成员,而且可以声明静态常量

    • 可以使用abstract修饰,因此它也可以被其他类继承

    • 可以使用final修饰,表示不能被继承

    • 编译后有自己的独立的字节码文件,只不过在内部类名前面冠以外部类名和$符号。

  • 和外部类不同的是,它可以允许四种权限修饰符:public,protected,缺省,private

    • 外部类只允许public或缺省的
  • 还可以在非静态内部类中使用外部类的所有成员,哪怕是私有的

  • 在外部类的静态成员中不可以使用非静态内部类哦

    • 就如同静态方法中不能访问本类的非静态成员变量和非静态方法一样
  • 在外部类的外面必须通过外部类的对象才能创建非静态内部类的对象(通常应该避免这样使用)

    • 如果要在外部类的外面使用非静态内部类的对象,通常在外部类中提供一个方法来返回这个非静态内部类的对象比较合适

    • 因此在非静态内部类的方法中有两个this对象,一个是外部类的this对象,一个是内部类的this对象

java 复制代码
public class TestMemberInnerClass {
    public static void main(String[] args) {
        Outer.outMethod();
        System.out.println("-----------------------");
        Outer out = new Outer();
        out.outFun();

        System.out.println("-----------------------------");
        Outer.Inner.inMethod();
        System.out.println("------------------------");
        Outer.Inner inner = new Outer.Inner();
        inner.inFun();

        System.out.println("-----------------------------");
        Outer outer = new Outer();
//        Outer.Nei nei = outer.new Nei();
        Outer.Nei nei = out.getNei();
        nei.inFun();
    }
}
class Outer{
    private static String a = "外部类的静态a";
    private static String b  = "外部类的静态b";
    private String c = "外部类对象的非静态c";
    private String d = "外部类对象的非静态d";

    static class Inner{
        private static String a ="静态内部类的静态a";
        private String c = "静态内部类对象的非静态c";
        public static void inMethod(){
            System.out.println("Inner.inMethod");
            System.out.println("Outer.a = " + Outer.a);
            System.out.println("Inner.a = " + a);
            System.out.println("b = " + b);
//            System.out.println("c = " + c);//不能访问外部类和自己的非静态成员
//            System.out.println("d = " + d);//不能访问外部类的非静态成员
        }
        public void inFun(){
            System.out.println("Inner.inFun");
            System.out.println("Outer.a = " + Outer.a);
            System.out.println("Inner.a = " + a);
            System.out.println("b = " + b);
            System.out.println("c = " + c);
//            System.out.println("d = " + d);//不能访问外部类的非静态成员
        }
    }

    class Nei{
        private String a = "非静态内部类对象的非静态a";
        private String c = "非静态内部类对象的非静态c";

        public void inFun(){
            System.out.println("Nei.inFun");
            System.out.println("Outer.a = " + Outer.a);
            System.out.println("a = " + a);
            System.out.println("b = " + b);
            System.out.println("Outer.c = " + Outer.this.c);
            System.out.println("c = " + c);
            System.out.println("d = " + d);
        }
    }

    public static void outMethod(){
        System.out.println("Outer.outMethod");
        System.out.println("a = " + a);
        System.out.println("Inner.a = " + Inner.a);
        System.out.println("b = " + b);
//        System.out.println("c = " + c);
//        System.out.println("d = " + d);
        Inner in = new Inner();
        System.out.println("in.c = " + in.c);
    }

    public void outFun(){
        System.out.println("Outer.outFun");
        System.out.println("a = " + a);
        System.out.println("Inner.a = " + Inner.a);
        System.out.println("b = " + b);
        System.out.println("c = " + c);
        System.out.println("d = " + d);
        Inner in = new Inner();
        System.out.println("in.c = " + in.c);
    }

    public Nei getNei(){
        return new Nei();
    }
}
静态内部类 非静态内部类
类角色 字节码文件 外部类名$内部类名 相同
修饰符 public,缺省,abstract,final 相同
父类或父接口 可以 相同
可以包含的成员 所有成员 不允许有静态成员
成员角色 修饰符 public、protected、缺省、private,final,static 没有static
依赖于外部类 依赖 相同
依赖于外部类的对象 不依赖 依赖
使用 在外部类中使用内部类 没有限制 在外部类的静态方法等中不能使用非静态内部类
在内部类中使用外部类 静态内部类中不能使用外部类的非静态成员 没有限制
在外部类的外面使用内部类的静态成员 外部类名.静态内部类名.静态成员 没有
在外部类的外面使用内部类的非静态成员 见下面的框1 见下面的框2
重名 外部类名.重名的成员名 外部类名.this.重名的成员

外部类名.静态内部类名 变量 = 外部类名.静态内部类名();

变量.非静态成员();
外部类名 变量1 = new 外部类();

外部类名.非静态内部类名 变量 = 变量1.new 非静态内部类名();

变量.非静态成员();

.....后续创作中

相关推荐
Grey Zeng20 小时前
Java SE 25新增特性
java·jdk·jdk新特性·jdk25
雨白21 小时前
Java 线程通信基础:interrupt、wait 和 notifyAll 详解
android·java
架构师沉默1 天前
设计多租户 SaaS 系统,如何做到数据隔离 & 资源配额?
java·后端·架构
Java中文社群1 天前
重要:Java25正式发布(长期支持版)!
java·后端·面试
每天进步一点_JL1 天前
JVM 类加载:双亲委派机制
java·后端
用户298698530141 天前
Java HTML 转 Word 完整指南
java·后端
渣哥1 天前
原来公平锁和非公平锁差别这么大
java
渣哥1 天前
99% 的人没搞懂:Semaphore 到底是干啥的?
java
J2K1 天前
JDK都25了,你还没用过ZGC?那真得补补课了
java·jvm·后端
kfyty7251 天前
不依赖第三方,不销毁重建,loveqq 框架如何原生实现动态线程池?
java·架构