java内部类——非静态内部类

目录

内部类

内部类的作用

内部类相关的设计

内部类分类

非静态内部类


内部类

一个类或者接口定义在另外一个类后者接口的内部

public class A1{//外部类
    class B1{}//内部类
    interface C1{}//内部接口
}

 将一个类定义置入另一个类定义中,这就叫作“内部类”

  • 内部类之外的类称为外部类
  • 内部类的名称必须区别于它所在的外部类,和其它类之间没有要求
内部类的全名叫做[外部类名称$内部类名称]
public class A1 {
    public class A1{} //语法报错
    class B1{} 语法正确,默认编译的结果名称为A1$B1.class
    }
class B1{}
  •  内部类可以访问其外部类的所有变量和方法
public class A1 {//外部类的范围限定词只能是public或者默认package
    private String name;
    public class B1 { //内部类的范围限定词可以是4种
        public void pp() {
            System.out.println(name);
            System.out.println(A1.this.name);//这里的A1.this用于表示A1类对象
            A1.this.name="ffff";
        // System.out.println(this.name);报错的原因是this用于指代当前类
//的对象,当前类B1中并没有属性name
            pp();
            A1.this.pp();
    }
}
    private void pp(){}
}
  • 外部类不能直接内部类的实现细节
public class A1 {
    private String name;
    public class B1 {
        private int age=99;
        public void ff() {
            System.out.println(name);
            System.out.println(A1.this.name);
            A1.this.name="ffff";
        }
        private void dd(){}
    }
    private void pp(){
        B1 b=new B1(); //如果需要在外部类中访问内部类的实现细节则需要构建内部类
//对象,然后通过内部类对象进行访问
        b.ff();
        System.out.println(b.age); //注意:可以直接访问内部类中的私有属性
        b.dd();//私有方法仍旧可以直接调用
    }
}
  •  内部类比外部类多了private/protected/static三个修饰符,这三个修饰符不能用在外部类上
  • 非静态内部类不能拥有静态成员
protected class B1 {
private int age = 99;
{ }//允许包含非静态代码块
private static String password="123456";//非静态内部类中不能包含静态属
性
static{ }//非静态内部类中不允许包含静态代码块
public B1() {//允许定义构造器和析构器方法
}
public static void hh(){} //非静态内部类中不允许包含静态方法

内部类的作用

内部类提供更好的封装

内部类可以直接访问外部类的私有成员

外部类不能直接访问内部类的成员,需要构建内部类对象才能访问

匿名内部类适合用于创建仅仅使用一次使用的类

内部类相关的设计

  • 分析事物时发现该事物描述还有事物,而且这个事物还在访问被描述事物的内容

例如牛和牛腿

如果一个事物离开另外一个事物后则没有任何意义,这种情况下建议使用内部类,不允许其他类访 问

  • 内部类能直接访问外部类中成员,是因为内部类持有了外部类的引用,即外部类名.this

内部类分类

在 Java 中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。广泛意义上的 内部类一般来说包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类。

内部类实际拥有外部类的一个引用,在构造函数中将外部类的引用传递进来。

非静态内部类

基础语法 

public class A1{
    protected class B1{}//静态内部类是protected static class B1{}
}

 非静态内部类的特点:

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

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

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

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

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

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

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

外部类只允许public或缺省的

  • 还可以在非静态内部类中使用外部类的所有成员,哪怕是私有的
  • 在外部类的静态成员中不可以使用非静态内部类哦

就如同静态方法中不能访问本类的非静态成员变量和非静态方法一样

  • 在外部类的外面必须通过外部类的对象才能创建非静态内部类的对象

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

  • 在创建非静态内部类对象时,一定要先创建起相应的外部类对象
public class A1 {
    public static void main(String[] args) {
        B1 b = new B1();
        B1.C1 cc = b.new C1(); //内部类的写法为[外部类名.内部类名],否则需要
import com.yan.B1.C1;则可以直接使用C1类。至于C1类是否可见取决于C1类的范围限定词
        System.out.println(cc);
    }
}
class B1 {
    public class C1 {
    }
}
  •  在任何非静态内部类中,都不能有静态数据、静态方法或者又一个静态内部类
语法错误
public class A1{
    public class B1{
        public static String name="yan";//语法错误,除非B1类是静态内部类
        static class B1{}
static{}//语法错误
        public static void pp(){}//语法错误
        public static class C1{}//语法错误
    }
}

注意内部类的可见性范围限制

访问方法:直接访问外部类中内部类中的成员

class B1 {
    private String pwd;
    private void dd(){}
    protected class C1 {
        private String name;
        private void pp(){
            System.out.println(pwd);//内部类可以直接访问外部类中的私有成员
            //另外的写法 B1.this.pwd
            dd();
            //另外的写法 B1.this.dd();
        }
    }
    public void ee(){
        //如果需要访问内部类中的成员,则必须首先创建内部类对象
        C1 cc=new C1();
        //通过构建的内部类对象则可以访问内部类中的私有成员
        cc.name="abc";
        cc.pp();
    }
}

 外部类.内部类 in=new 外部类().new 内部类();

public class A1 {
    public static void main(String[] args) {
        B1 b = new B1();
        B1.C1 cc=b.new C1();//内部类是否可以访问到,取决于内部类上的范围限定词
    }
}
class B1 {
    class C1{}
}

 in.内部类方法();

public class A1 {
    public static void main(String[] args) {
        B1 b = new B1();
        B1.C1 cc=b.new C1();
        cc.pp(); //是否可以访问pp方法取决于pp方法的范围限定词
    }
}
class B1 {
    class C1{
        public void pp(){}
    }
}

 注意内部类的可见性范围限制

class B1 {
    private class C1{//注意这个C1类只能在B1类中进行使用,其它位置不可见
        public void pp(){}
    }
}

 问题:

public class A1 {
    public A1(){
        System.out.println("aaaaa");
    }
    public static void main(String[] args) {
        new A1();//创建外部类对象和内部类无关,创建外部类对象并不会自动创建内部类对象
    }
    class C1 {
        public C1() {
            System.out.println("dddd");
        }
    }
}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
关于java程序员发展需要学习的路线整理集合 技术 应用技术 计算机基础知识 cpu mem disk net 线程,进程 第三方库 poi Jsoup zxing Gson 数据结构 树 栈 链表 队列 图 操作系统 linux 代码控制 自动化代码检查 sonar 代码规范 阿里巴巴Java开发规范手册 UMPAY——编码规范 日志规范 异常规范 网络 协议 TCP/IP HTTP hession file HTTPS 负载均衡 容器 JBOSS tomcat resin jetty 容灾 日志框架 开源框架 slf4j 框架实现 log4j logback commong logging jdk logger 测试框架 测试框架 junit easymock testng mockito bug管理 禅道 jira 开发工具 编程工具 eclipse myeclipse idea vi VS webstorm sublime text 版本控制 svn git 项目管理 maven Nexus Jenkins 工作软件 反编译软件 office系列 下载器 adobe系列 记录软件 思维导图 office--Note 邮件管理 性能优化 分层优化 系统级别 中间件级别 JVM级别 代码级别 分段优化 前端 web应用 服务应用 资源池 数据库 大数据与nosql zookeeper hadoop hbase mongodb strom spark java语言 语言语法基础 异常 泛型 内部类 反射 序列化 nIo 匿名类 包装类 优先级 引用 语言工具类库 容器类 集合 链表 map 工具类 系统类 日期类 数字类 字符串+正则 流 字符流 字节流 语言特性 继承 封装 多态 JVM 多线程与并发 GC机制 GC收集器类型 串行 CMS 并行 G1 算法 复制 标记清理 标记整理 分区 新生代 eden survivor 老年代(old区) 永久代(perm区) 版本变化 1.5 1.6 1.7 1.8 1.9 IO/NIO IO类型 同步阻塞 同步阻塞 基于信号 多路复用 异步IO 类加载机制 双亲委派 OSGI 算法 搜索 二分 排序 选择 冒泡 插入 快速 归并 堆 桶 基数 常用算法 贪婪 回溯 剪枝 动态规划 数据挖掘算法 KMP算法 GZZ算法 HASH分桶 关联规则算法 APRORIVE算法 分布式 负载均衡 水平伸缩 集群 分片 Key-hash 异步 一致性hash 消峰 分库分表 锁 悲观锁 乐观锁 行级锁 分布式锁 分区排队 一致性 一致性算法 paxos zab nwr raft gossip 柔性事务(TCC) 一致性原理 CAP BASE 中间件 数据库 mysql 存储引擎 索引 锁 oracle db2 缓存 redis 数据结构 持久 复制 cas 单线程 memcache eacache Tair 消息队列 jms Queue Topic kafka 持久 复制 Stream Partition rocketMQ RabbitMQ ActiveMQ 常用开源框架 Spring Spring MVC Spring WebFlow spring tx aop ioc Struts ibatis Mybatis CAS Dubbo 工作能力 软实力 应急能力 创新能力 管理能力 分享能力 学习能力 沟通能力 解决问题能力 经历 技术攻关案例 程序开发案例 程序设计案例 设计 设计原则 单一职责原则 开闭原则 里氏替换原则 依赖倒转原则 接口隔离原则 迪米特原则 设计模式 结构模式 适配器模式 桥接模式 组合模式 装饰模式 外观模式 享元模式 代理模式 创建模式 抽象工厂模式 工厂方法模式 建造这模式 原型模式 单例模式 行为模式 责任链模式 命令模式 解释器模式 迭代器模式 中介者模式 备忘录模式 观察者模式 状态模式 策略模式 模板方法模式 访问者模式 设计案例 UML 架构 系统架构能力 基本理论 扩展性设计 可用性设计 可靠性设计 一致性设计 负载均衡设计 过载保护设计 协议设计 二进制协议 文本协议 接入层架构设计 DNS轮询 动静态分离 静态化 反向代理 LVS F5 CDN 逻辑层架构设计 连接池 串行化技术 影子Master架构 批量写入 配置中心 去中心化 通讯机制 同步 RPC RMI 异步 MQ Cron 数据层架构设计 缓存优化 DAO&ORM; 双主架构 主从同步 读写分离 性能优化架构能力 代码级别 关联代码优化 cache对其 分支预测 copy on write 内联优化 系统优化 cache 延迟计算 数据预读 异步 轮询与通知 内存池 模块化 工程架构能力 开发语言 运维与监控 监控 系统监控 日志监控 流量监控 接口监控 数据库监控 业务监控 性能监控 告警 日志 设计模式 数据结构与算法 各种工具

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值