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日

相关推荐

  • Java自学之String类

    在实际项目开发中,String是一个必须使用的程序类,可以说是项目的核心组成类。在Java程序里所有的字符串都要求使用【’‘】进行定义,同时也可以利用【+】实现字符串的连接处理。 …

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

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

    2021年5月28日
    1.1K
  • Spring Boot的常用注解

    未来的框架趋势是“约定大于配置”,代码的封装会更加严密。开发人员会将更多的精力放在代码的整体优化和业务逻辑上,所以注解式编程会被更加广泛地使用。那么什么是注解?Spring Boo…

    2024年8月29日
    261
  • spring4.x学习之创建工程

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

    2019年3月19日
    1.7K
  • MyBatis之MyBatis-Generator标签配置及意义

    DTD 标签 <generatorConfiguration/>: 根标签,所有的配置都必须在该标签内配置;没有属性 <properties/>: 主要引用外部的pro…

    2019年12月27日
    1.7K
  • spring boot练习篇之用户登录系统【接口篇】

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

    2021年5月25日
    1.5K
  • STS插件mybatis-generator安装及使用

    断断续续学习Java也有好长时间了,没有师傅带,没有项目练手,学习超级慢,也很烦。视频、书籍翻看了一大推,还是没有目标。 相信滴水成海,外加条条大路通罗马,只要坚持,自己终能达成目…

    2019年12月27日
    2.1K
  • Spring Tools学习之JAVA开发环境搭建【windows 10】

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

    2018年12月6日
    2.7K
  • Java自学之I/O编程

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

    2020年12月21日
    1.1K
  • Java自学之类与对象

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

    2020年11月25日
    1.1K

发表回复

Please Login to Comment