第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 非静态内部类名();

变量.非静态成员();

.....后续创作中

相关推荐
I_Am_Me_6 分钟前
【JavaEE进阶】 JavaScript
开发语言·javascript·ecmascript
重生之我是数学王子16 分钟前
QT基础 编码问题 定时器 事件 绘图事件 keyPressEvent QT5.12.3环境 C++实现
开发语言·c++·qt
xmh-sxh-131416 分钟前
jdk各个版本介绍
java
Ai 编码助手17 分钟前
使用php和Xunsearch提升音乐网站的歌曲搜索效果
开发语言·php
学习前端的小z21 分钟前
【前端】深入理解 JavaScript 逻辑运算符的优先级与短路求值机制
开发语言·前端·javascript
神仙别闹29 分钟前
基于C#和Sql Server 2008实现的(WinForm)订单生成系统
开发语言·c#
XINGTECODE30 分钟前
海盗王集成网关和商城服务端功能golang版
开发语言·后端·golang
天天扭码36 分钟前
五天SpringCloud计划——DAY2之单体架构和微服务架构的选择和转换原则
java·spring cloud·微服务·架构
程序猿进阶36 分钟前
堆外内存泄露排查经历
java·jvm·后端·面试·性能优化·oom·内存泄露
FIN技术铺41 分钟前
Spring Boot框架Starter组件整理
java·spring boot·后端