Java自学之内部类

内部类是一种常见的嵌套结构,利用这样的结构使得内部类可以与外部类共存,并且方便地进行私有操作的访问。

内部类基本概念

内部类(内部定义普通类、抽象类、接口的统称)是指一种嵌套的结构关系,即在一个类的内部除了属性和方法外还可以继续定义一个类结构,这样就使得程序的结构定义更加灵活。

package cn.uihtml.demo;
 class Outer{
     private String msg = 'www.uihtml.cn';
     public void fun() {
         Inner in = new Inner();
         in.print();
         // 访问内部类的私有属性
         System.out.println(in.info);
     }
     class Inner {
         private String info = '内部类私有属性';
         public void print() {
             System.out.println(Outer.this.msg);
         }
     }
 }
package cn.uihtml.demo;
 class JavaDemo {
     public static void main(String[] args) {
         Outer out = new Outer();
         out.fun();
     }
 }

在内部类的结构中,不仅内部类可以方便地访问外部类的私有成员,外部类也同样可以访问内部类的私有成员。内部类本身是一个独立的结构,这样在进行普通成员属性访问时,为了明确地标记处属性是外部类所提供,可以采用【“外部类.this.属性”】的形式进行标注。

需要注意的是,内部类虽然被外部类所包裹,但是其本身也属于一个完整类,所以也可以直接进行内部类对象的实例化,此时可以采用以下的语法格式。

外部类.内部类 内部类对象 = new 外部类().内部类();

在此语法格式中,要求必须先获取相应的外部类实例化对象后,才可以利用外部类的实例化对象进行内部类对象实例化操作。

内部类不仅可以在类中定义,也可以应用在接口和抽象类中,即可以定义内部的接口或内部抽象类。

package cn.uihtml.demo;
 interface IChannel {
     public void send(IMessage msg);
     interface IMessage{
         public String getContent();
     }
 }
package cn.html.demo;
 class ChannelImpl implements IChannel {
     @Override
     public void send(IMessage msg) {
         System.out.println('发送消息:' + msg.getContent());
     }
     class MessageImpl implements IMessage {
         @Override
         public String getContent() {
             return 'www.uihtml.cn'
         }
     }
 }
package cn.uihtml.demo;
 class JavaDemo {
     public static void main(String[] args) {
         IChannel channel = new ChannelImpl();
         channel.send(((ChannelImpl) channel).new MessageImpl())
     }
 }

static定义内部类

在进行内部类定义的时候,也可以通过static关键字来定义,此时的内部类不再受外部类实例化对象的影响,所以等同于是一个“外部类”,内部类的名称为“外部类.内部类”。使用static定义的内部类只能够调用外部类中static定义的结构,并且在进行内部类实例化的时候也不再需要先获取外部类实例化对象,static内部类对象实例化格式如下。

外部类.内部类 内部类对象 = new 外部类.内部类();
package cn.uihtml.demo;
 class Outer {
     private static final String MSG = 'www.uihtml.cn';
     static class Inner {
         public void print() {
             System.out.println(Outer.MSG);
         }
     }
 }
package cn.uihtml.demo;
 class JavaDemo {
     public static void main(String[] args) {
         Outer.Inner in = new Outer.Inner();
         in.print();
     }
 }

匿名内部类

在一个接口或抽象类定义完成后,在使用前都需要定义专门的子类,随后利用子类对象的向上转型才可以使用接口或抽象类。但是在很多时候某些子类可能只是用一次,那么单独为其创建一个类文件就会非常浪费,此时就可以利用匿名内部类的概念来解决此类问题。

package cn.uihtml.demo;
 interface IMessage {
     public void send(String str);
 }
package cn.uihtml.demo;
 class JavaDemo {
     public static void main(String[] args) {
         IMessage msg = new IMessage() {
             public void send(String str) {
                 System.out.println(str);
             }
         };
         msg.send('www.uihtml.cn');
     }
 }

Lambba表达式

Lambba表达式是JDK1.8中引入的重要技术特征。所谓的Lambba表达式,是指应用在SAM(Single Abstract Method,含有一个抽象方法的接口)环境下的一种简化定义形式,用于解决匿名内部类的定义复杂问题,在Java中Lambba表达式的基本语法形式如下。

// 定义方法体
 (参数1,参数2,…)->{方法体}
 // 直接返回结果
 (参数1,参数2,…)-> 语句

在给定的格式中,参数与要覆写的抽象方法的参数对应,抽象方法的具体操作就通过方法体来进行定义。

package cn.uihtml.demo;
 interface IMessage {
     public void send(String str);
 }
package cn.uihtml.demo;
 class JavaDemo {
     public static void main(String[] args) {
         IMessage msg = (str) -> {
             System.out.println('发送消息:' + str);
         }
         msg.send('www.uihtml.cn');
     }
 }

在进行Lambba表达式定义的过程中,如果要实现的方法体只有一行,则可以省略“{}”。

在Lambba表达式中已经明确要求Lambba是应用在接口上的一种操作,并且接口中只允许定义一个抽象方法。但是在一个项目开发中往往会定义大量的接口,而为了分辨出Lambba表达式的使用接口,可以在接口上使用@FunctionInterface注解声明,这样表示此为函数式接口,里面只允许定义一个抽象方法。

package cn.uihtml.demo;
 @FunctionInterface
 interface IMessage {
     public void send(String str);
 }

需要注意的是,在函数式接口中依然可以定义普通方法和静态方法。

方法的引用

在Java中利用对象的引用传递可以实现不同的对象名称操作同一块堆内存空间的操作,而从JDK1.8开始,方法也支持引用操作,这样就相当于为方法定义了别名。方法引用的形式一共有有以下4种。

// 引用静态方法
 类名称::static 方法名称
 // 引用某个对象的方法
 实例化对象:: 普通方法
 // 引用特定类型的方法
 特定类:: 普通方法
 // 引用构造方法
 类名称:: new

链表

在项目开发种数组是一个重要的逻辑组成。传统数组中最大的缺陷在于其一旦声明则长度固定,不便于程序开发,而要想要解决这一缺陷,就可以利用链表数据结构实现。

链表(动态数组)的本质是利用对象引用的逻辑关系来实现类似数组的数据存储逻辑,一个链上由若干个节点(node)所组成,每一个节点依靠对上一个节点的引用形成一个“链”的形式。

数组本身是需要进行多个数据的信息保存,但是数据本身并不能够描述出彼此间的先后顺序,所以就需要将数据包装在节点(node)中,每一个节点除了要保存数据信息外,一定还要保存有下一个节点(node)的引用,而在链表中会保存一系列的节点对象。

在进行Node类设计时,为了避免程序开发中可能出现的ClassCastException安全隐患,对于保存的数据类型都用泛型进行定义,这样就可以保证在一个链表中的数据类型统一。

package cn.uihtml.demo;
 class Node {
     private E data;
     private Node next;
     public Node(E data) {
         this.data = data;
     }
     public E getData() {
         return this.data;
     }
     public void setNext(Node next) {
         this.next = next;
     }
     public Node getNext() {
         return this.next;
     }
 }
package cn.uihtml.demo;
 class LinkDemo {
     public static void main(String[] args) {
         Node n1 = new Node('火车头');
         Node n2 = new Node('车厢一');
         node n3 = new Node('车厢二');
         node n4 = new Node('车厢三');
         node n5 = new Node('车厢四');
         node n6 = new Node('车厢五');
         printNode(n1);
     }
     public static void printNode(Node node) {
         if (node != null) {
             System.out.print(node.getData() + '、');
             printNode(node.getNext());
         }
     }
 }

原创文章,作者:ZERO,如若转载,请注明出处:https://www.edu24.cn/course/java/java-inner-class.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
ZEROZERO
上一篇 2020年12月11日
下一篇 2020年12月16日

相关推荐

  • Java自学之抽象类与接口

    面向对象程序设计中,类继承的主要作用的扩充已有类的功能。子类可以根据自己的需要选择是否要覆写父类中的方法,所以一个设计完善的父类是无法对子类做出任何强制性的覆写约定。为了解决这样的…

    2020年12月7日
    1.3K
  • spring4.x学习之用户登录与注册

    在之前的文章中我已经把后端工程项目创建好了,接下来就是编写项目了。 首先,我先创建一个数据库。数据库使用的是MySQL,数据库管理工具用的是Navicat。 打开数据库管理工具Na…

    2019年3月21日
    2.1K
  • Java自学之泛型

    在Java语言中,为了方便接收参数类型的统一,提供了核心类Object,利用此类对象可以接收所有类型的数据(包括基本数据类型和引用数据类型)。但是由于其所描述的数据范围过大,所以在…

    2020年12月8日
    1.3K
  • spring4.x学习之创建工程

    断断续续学习Java有两三个月了,目前还是处于入门阶段。关于java及spring那些的设计理念方面的理论知识,不花费大量精力及时间是看不懂的(至少对于我这么一个前端转后端的初学者…

    2019年3月19日
    1.9K
  • Spring Tools学习之JAVA开发环境搭建【windows 10】

    一直以来都想学习JAVA,但是苦于找不到门路,网上学习资料要不看不懂,要不需要金钱。 终于,迫于生活与年龄的压力,下定决心,学习JAVA。 写下此文档,记录一下自己学习JAVA之路…

    2018年12月6日
    2.9K
  • JAVA学习之多线程知识点整理

    1、什么是进程?什么是线程? 进程是一个应用程序。线程是一个进程中的执行场景或者执行单元。一个进程可以启动多个线程。进程之间内存独立不共享。同一个进程中的线程之间,堆内存和方法区内…

    2020年6月19日
    1.3K
  • Java自学之多线程编程

    多线程编程是Java语言最为重要的特性之一。利用多线程技术可以提升单位时间内的程序处理性能,也是现代程序开发中高并发的主要设计模式。 进程与线程 进程是一个应用程序。线程是一个进程…

    2020年12月16日
    1.6K
  • Java自学之类结构扩展

    面向对象中的核心组成是类与接口,在项目中会利用【包】进行一组相关类的管理,这样适合于程序代码的部分更新,也更加符合面向对象封装性的概念,同时合理地使用封装也可以方便地实现实例化对象…

    2020年12月10日
    1.3K
  • JAVA基础知识整理

    终于下定决心2020年转JAVA开发,自学之路坎坷曲折。俗话说的话,好记性不如烂笔头。如果有小伙伴们也像我一样在JAVA自学之路上徘徊,那就关注一下我的博客网站。我会不定期更新一下…

    2020年1月11日
    1.8K
  • Java自学之类与对象

    定义 类是由成员属性和方法组成。成员属性主要定义类的一个具体信息,实际上一个成员属性就是一个变量,而方法是一些操作的行为。类的定义基础语法如下。 一个类定义完成后并不能够被直接使用…

    2020年11月25日
    1.3K

发表回复

登录后才能评论