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

Like (0)
Donate 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
ZEROZERO
Previous 2020年12月11日
Next 2020年12月16日

相关推荐

  • spring boot练习篇之用户登录系统【接口篇】

    写在前面 抛弃JSP,只做纯粹的前后端分离项目。 作为一个资深前端工作者,想要转JavaWeb开发,无论是书籍,还是网上视频、资料,竟然没有一篇能清楚明白地讲解怎样搭建一个前后端分…

    2021年5月25日
    1.5K
  • Java自学之数组

    在Java中数组是一组相关变量的集合,属于引用数据类型。 定义 数组引用传递分析 数组属于引用数据类型,在数组使用时需要通过关键字new开辟堆内存空间,一块堆内存空间也可以同时被多…

    2020年11月26日
    1.2K
  • spring boot练习篇之用户登录系统【接入数据库】

    抛弃JSP,只做纯粹的前后端分离项目。 写在前面 学习基础知识是枯燥无味的,之所以会这样,多数是因为心不静,对于如何运用它,感到茫然。所以建议大家在学习Java基础知识的时候,一定…

    2021年5月28日
    1.2K
  • JAVA学习之多线程知识点整理

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

    2020年6月19日
    1.2K
  • 如何使用IDEA2020.2新建servlet工程

    最近自学java时,发现IDEA更新到2020.2版本时,在新建工程时,有了明显的改动。由于小编刚学到servlet,IDEA这一突然间的改动,导致小编不会新建servlet工程了…

    2020年8月17日
    5.8K
  • Java自学之异常的捕获与处理

    在程序开发中,程序的编译与运行是两个不同的阶段,编译主要针对的是语法检测,而在程序运行时却有可能出现各种各样的错误导致程序中断执行,那么这些错误在Java中统一称为异常。 异常处理…

    2020年12月11日
    1.3K
  • Java自学之泛型

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

    2020年12月8日
    1.2K
  • Java自学之抽象类与接口

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

    2020年12月7日
    1.1K
  • Java自学之I/O编程

    I/O(Input/Output,输入/输出)可以实现数据的读取与写入操作,Java针对I/O操作的实现提供了java.io工具包,此包的核心组成由File类、InputStrea…

    2020年12月21日
    1.2K
  • JavaWeb入门案例之用户注册

    前言 之前把Java的基础知识系统的过了一遍,目前总算可以看懂Java代码了,接下来就是要学习Java开发框架(主要是springMVC)。 下面用一个用户注册的小案例,来总结一下…

    2021年1月13日
    1.5K

发表回复

Please Login to Comment