[Java]面向对象-内部类

news2024/9/21 22:43:48

类的五大成员:属性、方法、构造方法、代码块、内部类

内部类

在一个类里边再定义一个类。可以在外部其他类中创建内部类对象并调用它的方法

public class Outer {//外部类
    public class inner{//内部类

    }
}
内部类使用时机: 
  • 内部类表示的事物是外部类的一部分
  • 内部类单独出来没有任何意义
特点:

1.内部类可以直接访问外部类的成员,包括私有

2.外部类要访问内部类的成员必须创建对象

package day15.demo10;

public class Car {
    String carname;
    int age;
    String color;

    class engine{
        String name;
        int age;

        public void show(){
            System.out.println(name);
            System.out.println(carname);
        }
    }
    engine engine = new engine();
    public void show(){
        System.out.println(carname);
        System.out.println(engine.name);
    }
}

 内部类分类

  • 成员内部类
  • 静态内部类
  • 局部内部类
  • 匿名内部类
成员内部类:

写在成员位置的,属于外部类的成员

可以被权限修饰符修饰

类定义在了成员位置 (类中方法外称为成员位置,无static修饰的内部类)

使用方法:

 外部类.内部类。 // 访问内部类的类型都是用 外部类.内部类

获取成员内部类对象:

法一:在外部类中编写方法,对外提供内部类对象

public class Outer {
    String outername;
    private class Inner{
        String innername = null;
    }
    public Inner getinstance(){
        return new Inner();
    }
}
===========================================================================================
public class main {
    public static void main(String[] args) {
//        Outer.Inner inner = new Outer().new Inner();
//        inner.innername = "hello";
//        System.out.println(inner.innername);
        Outer outer = new Outer();
        outer.getinstance();
        System.out.println(outer.getinstance());
    }
}

法二:直接创建格式:外部类.内部类 对象名 = 外部类对象.内部类对象

public class main {
    public static void main(String[] args) {
        Outer.Inner inner = new Outer().new Inner();
        inner.innername = "hello";

        System.out.println(inner.innername);
    }
}

内部类访问外部类的成员变量 

public class Outer {
    private int a = 10;
    
    class Inner{
        private int a = 20;

        public void show(){
            int a = 30;
            System.out.println(a);
            System.out.println(this.a);
            System.out.println(Outer.this.a);
        }
    }
}

为什么是Outer.this.a?

通过Java内存分析工具我们可以看到,内部类Inner中隐含一个Outer.this来记录外部类的地址值,当内部类访问外部类的成员变量的时候会通过内部类隐含的Outer.this来访问Outer类进而访问其成员变量。

 可以看到,内部类和外部类是两个不同的类,通过Outer.this来记录内部类外部类的关系

静态内部类: 

成员内部类被static修饰时就称为静态内部类

静态内部类只能访问外部类中的静态变量和静态方法,如果要想访问非静态的需要创建对象

创建静态内部类对象格式:外部类.内部类 对象名 = new 外部类.内部类();

调用非静态方法的格式:先创建对象,用对象调用

调用静态方法格式:外部类.内部类.方法名();

public class Outer {
    int a = 10;
    static int b = 20;
    static class Inner{
        public void show1(){
            Outer outer = new Outer();
            System.out.println(outer.a);
            System.out.println(b);
            System.out.println("show1");
        }

        public static void show2(){
            System.out.println("show2");
        }
    }
}
==========================================================================================
public class main {
    public static void main(String[] args) {
        Outer.Inner o = new Outer.Inner();
        o.show1();
        Outer.Inner.show2();//调用静态方法
    }
}
局部内部类: 

1.将内部类定义在方法内就叫做局部内部类,类似于方法里边的局部变量

2.外界无法直接使用,需要在方法内部创建对象并调用

3.该类可以直接访问外部类的成员,也可以直接访问方法内的局部变量

 注 : 不能用权限修饰符修饰

public class Outer {
    int b = 20;
    public void show(){
        int a = 10;
        class Inner{//局部内部类
            String name;
            int age;

            public void method(){
                System.out.println(b);
                System.out.println("Inner");
            }

            public void method2(){
                System.out.println("Inner static");
            }
        }

        Inner inner = new Inner();
        System.out.println(inner.name);
        System.out.println(inner.age);
        inner.method();
        inner.method2();
    }
}
匿名内部类: 

匿名内部类本质上就是隐藏了名字的内部类,是内部类的简化写法

格式:

new 类名或者接口名() {
     重写方法;
};

包含了:

  • 继承或者实现关系

  • 方法重写

  • 创建对象

public interface swim {
    void swim();
}
===========================================================================================
public class main {
    public static void main(String[] args) {
        new swim(){

            @Override
            public void swim() {
                System.out.println("swim");
            }
        };
    }
}

绿色的框表示的是没有名字的对象,new是用来创建此类。类实现了swim接口实现的重写 。

如果swim是类的话,就是继承关系,匿名内部类继承了名为swim的抽象类

 main$1为编译生成的匿名内部类字节码文件,可以通过Javap进行反编译字节码文件,可以看到匿名内部类与接口之间的实现关系或者和类之间的继承关系

使用时机:

一个类在只使用一次时,在使用一个类时需要再创建一个类太麻烦了,此时使用匿名内部类的形式简化代码。当将匿名内部类调用的接口赋值给一个对象时候,此时就形成了接口的多态。

package day15.demo15;

public class main {
    public static void main(String[] args) {
        new swim(){

            @Override
            public void swim() {
                System.out.println("swim");
            }
        }.swim();


//        new Outer() {
//            @Override
//            public void eat() {
//
//            }
//        };
//        dog dog = new dog();
//        method(dog);传统方法

        method(//匿名内部类形式 多态
                new Outer() {
                    @Override
                    public void eat() {
                        System.out.println("狗吃屎");
                    }
                }
        );
    }
    public static void method(Outer a){
        a.eat();
    }
}
注意事项:
  1. 匿名内部类是隐藏了名字的类,可以写在成员位置,也可以写在局部位置
  2. 匿名内部类包含了继承或实现,方法重写,创建对象。 整体就是一个类的子类对象或者接口实现类的对象
  3. 当一个方法的参数是接口或者类时,以接口为例,可以传递这个接口的实现类对象,如果实现类只需要使用一次,就可以用匿名内部类简化代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2051584.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

打造高可用集群的基石:深度解析Keepalived实践与优化

高可用集群 集群类型 集群类型主要分为负载均衡集群(LB)、高可用集群(HA)和高性能计算集群(HPC)三大类。每种集群类型都有其特定的应用场景和优势。 1. 负载均衡集群(LB) 负载均衡集…

drawio的问题

drawio的问题 先给出drawio的链接https://app.diagrams.net/ 我在用overleaf写论文的过程中,发现了一个问题,就是使用drawio画好图之后,只能保存以下几个选项: 但是不管是什么类型,在overleaf上面图片都不显示。如果…

SpringBoot如何做自动配置

目录 一、什么是springboot的自动配置? 二、Enable注解 三、springboot自动配置流程 ComponentScan SpringBootConfiguration EnableAutoConfiguration注解 condition的几个注解: 四、自定义启动类 需求: 参考: 实现步…

使用JQUERY请求数据出现500报错

我在写项目的时候遇到了一个问题,就是在存商品id的时候我将它使用了JSON.stringify的格式转换了!!!于是便爆出了500这个错误!!! 我将JSON.stringify的格式去除之后,它就正常显示了&a…

【数学建模】趣味数模问题——四人追逐问题

问题描述: 如图所示,在正方形ABCD的四个顶点各有一个人。在初始时刻 t0 时,四人同时出发,以匀速 v 沿顺时针方向朝下一个人移动。如果他们始终对准下一个人为目标行进,最终结果会如何?需要作出各自的运动轨…

路径规划 | 灰狼算法+B样条曲线优化无人机三维路径规划(Matlab)

目录 效果一览基本介绍程序设计参考文献 效果一览 基本介绍 灰狼算法B样条曲线优化无人机三维路径规划(Matlab) 群智能路径规划算法。三维灰狼算法(GWO)加B样条曲线优化的matlab代码。无人机(UAV)路径规划…

QT:安装软件

QT 介绍 QT是一个跨平台的C应用程序开发框架,具有广泛的应用领域和强大的功能。 定义:QT是一个跨平台的C图形用户界面应用程序框架,为开发者提供了建立艺术级图形界面所需的所有功能。 特点:QT具有短平快的优秀特质,即…

csrf漏洞(二)

本文仅作为学习参考使用,本文作者对任何使用本文进行渗透攻击破坏不负任何责任。 前言: 本文依靠phpstudy以及dvwa靶场进行操作,具体搭建流程参考:xss漏洞(二,xss靶场搭建以及简单利用) 前篇…

Godot关于3d射线投射的一些问题

首先你得把刚体模式激活如图否则将是空对象 为了区分其他坐标颜色园哥把射线设置成紫色以示区别 另外运行模式中貌似射线不可见只在调试模式中可见。最后查看调试器 成功碰撞一个名为主角的物体,也许都命中了但是方法只返回第一个命中的物体,吐槽一下&a…

场外个股期权如何发出行权指令?

场外期权行权指令也就是平仓指令的意思,一般场外个股期权交易有三种方式开仓和行权平仓指令,分别是市价,限价和半小时询价,跟普通股票的买卖和交易方式类似,唯一区别是手动发出场外个股期权的行权指令,下文…

Linux系统中的高级系统资源管理技术:systemd资源控制

在当今信息技术的快速发展中,服务器的性能管理和资源分配变得尤为重要。Linux操作系统以其灵活性和可定制性在服务器领域广受欢迎。而在Linux系统中,systemd资源控制作为一项重要的高级系统资源管理技术,为管理员提供了精细化控制和调整系统服…

STM32标准库学习笔记-2.GPIO

参考教程:【STM32入门教程-2023版 细致讲解 中文字幕】 标准库开发新建工程准备工作: 建立工程文件夹,Keil中新建工程,选择型号STM32F103C8T6工程文件夹里建立Start、Library、User等文件夹,复制固件库里面的文件到工…

【leetcode详解】实现一个魔法字典(思路详解 错误反思)

关于输入的解释: ‘ 输入 ’下方第一个列表是“调用函数”,第二个列表是“提供的字符串”,二者一一对应 如示例中buildDict对应[[“hello”, "leetcode"]],即构建的字典包含 “hello” 和 "leetcode" 两个字…

基于laravel开发的开源交易所源码|BTC交易所/ETH交易所/交易所/交易平台/撮合交易引擎

开源交易所,基于Laravel开发的交易所 | BTC交易所 | ETH交易所 | 交易所 | 交易平台 | 撮合交易引擎。本项目有完整的撮合交易引擎源码、后台管理(后端前端)、前台(交易页面、活动页面、个人中心等) 特色:…

smbms

框架 数据库 项目如何搭建 考虑使不使用maven&#xff0c;依赖与jar包 项目搭建准备工作 搭建一个maven web项目配置tomcat测试项目是否能够跑起来导入项目中会遇到的jar包 //jsp、servlet、mysql驱动、jstl、stand.... <dependency><groupId>junit</groupI…

链表的删除 203、237、19 链表的遍历 430

203. 移除链表元素&#xff08;简单&#xff09; 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 解法一、递归 见代码 链表的定义具有递归的性质&#xff0c;所以遍历也可以以递归的方…

百度AI智能云依赖库OpenSSL库和Curl库及jsoncpp库安装

开发百度AI项目时&#xff0c;需要用到https协议&#xff0c;因此需要安装OpenSSl和curl库。 若只安装curl库&#xff0c;只支持http协议&#xff0c;不支持https协议。此外&#xff0c;还需要jsoncpp库&#xff0c;用以组包及解析与百度AI通信的json格式协议。 1.Ubuntu上安装…

修饰者模式

文章目录 1.简单介绍2.修饰器的优缺点3.模式结构3.案例分析4.总结5.装饰器模式和代理模式对比 1.简单介绍 装饰器模式&#xff08;Decorator Pattern&#xff09;也叫包装模式(Wrapper Pattern),是指在不改变原有对象的基础之上&#xff0c;将功能附加到对象上&#xff0c;提供…

【Linux —— 线程控制】

Linux —— 线程控制 进程和线程进程线程进程和线程的关系进程的优缺点Linux进程VS线程 Linux线程控制POSIX线程库创建线程线程等待线程终止线程分离 进程和线程 进程 进程是一个正在执行的程序实例&#xff0c;拥有独立的地址空间、数据段、代码段、堆栈以及系统资源&#xf…

大型语言模型(LLM)——直接偏好优化完整指南

概述 将大型语言模型 (LLM) 与人类价值观和偏好相结合是一项挑战。传统方法&#xff0c;例如 [从人类反馈中强化学习](&#xff08;RLHF&#xff09;通过整合人类输入来完善模型输出&#xff0c;为这一领域的研究铺平了道路。然而&#xff0c;RLHF 可能非常复杂且资源密集&…