重学java 26.面向对象 内部类⭐

news/2024/10/7 23:15:43/

“别担心,你一定能如愿。”

                                    —— 24.4.29

1.什么时候使用内部类:

        当一个事物的内部,还有一个部分需要完整的结构去描述,而内部的完整结构又只为外部事物提供服务,那么整个内部的完整结构最好使用内部类

        比如:人类有心脏,人类本身需要用属性、行为去描述,那么人类内部的心脏也需要心脏特殊的属性和行为去描述,此时心脏就可以定义成内部类,人类中的一个心脏类

2.在java中允许一个类的定义位于另外一个类的内部,前者被称之为内部类,后者被称之为外部类

        class A{

                class B{

                                

                }

        }

        类A就是类B的外部类

        类B就是类A的内部类

3.分类:

        成员内部类(静态,非静态)

        局部内部类

        匿名内部类(重点)

一、静态成员内部类

1.格式:

        直接在定义内部类的时候加上static关键字

        public class A{

                static class B{

                }

        }

2.注意:

        a、内部类可以定义属性、方法、构造等

        b、静态内部类可以被final或者abstract修饰

              被final修饰之后,不能被继承

              被abstract修饰之后,不能new

        c、静态内部类不能调用外部的非静态成员

        d、内部类还可以被四种权限修饰符修饰

二、成员内部类

1.调用静态成员内部类

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

java">public class Person {public void eat(){System.out.println("人要干饭");}static class Heart{public void jump(){System.out.println("心脏跳动");}}
}
java">public class Demo134StaticInnerClass {public static void main(String[] args) {// 外部类.内部类 对象名 = new 外部类.内部类()Person.Heart heart = new Person.Heart();heart.jump();}
}

2.调用非静态成员内部类

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

Person外部类,Heart内部类,jump内部类Heart里的方法

java">public class Person {public void eat(){System.out.println("人要干饭");}class Heart{Heart(){}public void jump(){System.out.println("心脏跳动");}}
}
java">public class Demo135StaticInnerClass2 {public static void main(String[] args) {// 外部类.内部类 对象名 = new 外部类().new 内部类()Person.Heart heart = new Person().new Heart();heart.jump();}
}

外部类的成员变量和内部类的成员变量以及内部类的局部变量重名时,怎么区分?

示例:

        外部类Student 内部类Heart 内部类的方法display

java">public class Student {String name = "金莲";class Heart{String name = "大朗";public void display(String name){// 内部类的局部变量System.out.println(name);// 内部类的成员变量System.out.println(this.name);// 外部类的成员变量System.out.println(Student.this.name);}}
}

测试类

java">public class Demo136StaticInnerClass3 {public static void main(String[] args) {Student.Heart heart = new Student().new Heart();heart.display("小明");}
}

三、局部内部类

1.局部内部类的基本操作

        可以定义在方法中、代码块中、构造方法

示例:

Person外部类和Heart内部类

java">public class Person {public void eat(){class Heart{public void jump(){System.out.println("心脏哐哐哐的跳动");}}new Heart().jump();}
}

测试类

java">public class Demo137StaticInnerClass4 {public static void main(String[] args) {Person person = new Person();person.eat();}
}

2.局部内部类实际操作

1.接口类型作为方法参数传递和返回

        接口作为方法参数,传递实参时,传递的是实现类对象

        

示例:

        接口

java">public interface USB {public abstract void open();
}

        实现类

java">public class Mouse implements USB{@Overridepublic void open() {System.out.println("鼠标打开");}
}

        测试类

java">    public static void main(String[] args) {Mouse mouse = new Mouse();method(mouse);System.out.println("————————————————————————");
//        USB usb = new Mouse();USB usb = method01();usb.open();}/*接口作为方法参数返回,实际返回的是实现类对象USB usb = mouse ——> 多态*/public static void method(USB usb){usb.open();}/*接口作为返回值类型,传递实参时,传递的是实现类对象*/public static USB method01(){Mouse mouse = new Mouse();return mouse;//return new Mouse();}
}

2.抽象类作为方法参数和返回值

        ① 抽象类作为方法参数传递,传递实参时,传递的是其子类对象

        ② 抽象类作为方法返回值类型返回时,实际返回的是其子类对象

示例:

        抽象类

java">public abstract class Animal {public abstract void eat();
}

        实现类

java">public class Dog extends Animal{@Overridepublic void eat() {System.out.println("狗啃骨头");}
}

        测试类

java">public class Demo139StaticInnerClass6 {public static void main(String[] args) {Dog dog = new Dog();method01(dog);System.out.println("————————————————————");Animal animal = method02();animal.eat();}public static void method01(Animal animal){animal.eat();}public static Animal method02(){Dog dog = new Dog();return dog;}
}

3.普通类做方法参数和返回值

        普通类作为方法参数传递,传递的是对象
        普通类作为方法返回值返回,返回的是对象

示例:

        普通类

java">public class Person {public void eat(){System.out.println("人要吃饭");}
}

        测试类

java">public class Demo140StaticInnerClass7 {public static void main(String[] args) {Person person = new Person();method01(person);System.out.println("————————————————————————");Person person1 = method02();method01(person1);}public static void method01(Person person){person.eat();}public static Person method02(){Person person = new Person();return person;}
}

4.局部内部类实际操作

        USB接口

java">public interface USB {void open();
}

        测试类

java">public class Demo141StaticInnerClass8 {public static void main(String[] args) {// USB usb = new Mouse()USB usb = method();usb.open();}public static USB method(){// 局部内部类class Mouse implements USB {@Overridepublic void open() {System.out.println("鼠标打开了");}}Mouse mouse = new Mouse();return mouse;}
}

四、匿名内部类⭐

1.定义

        所谓的匿名内部类:可以理解为没有显式声明出类名的内部类

2.问题描述

        我们如果想实现接口,简单使用一次抽象方法,我们就需要创建一个实现类,实现这个接口,重写抽象方法,还要new实现类对象,如果我们单纯使用一次接口中的方法,我们能否不这么麻烦进行实现吗?

        a、创建实现类,实现接口

        b、重写方法

        c、创建实现类对象

        d、调用方法

3.单纯使用接口方法

        如果我们想单纯使用一下接口中的方法,我们可以四步合一

4.匿名内部类学习方法

        按照一种格式来学习,这一种格式代表了实现类对象或是子类对象

5.格式

     实现类对象

        ①:

        new 接口/抽象类(){

                重写方法

        }.重写的方法():

       

        ②:

        类名 对象名 = new 接口/抽象类(){

                重写方法

        }

        对象名.重写的方法

java">public class Demo142StaticInnerClass9 {public static void main(String[] args) {// 重写接口方法new USB() {@Overridepublic void open() {System.out.println("USB打开了");}@Overridepublic void close() {System.out.println("USB关闭了");}}.open();System.out.println("——————————————————————————————————————");// 有名对象,可以调用多个方法USB usb = new USB() {@Overridepublic void open() {System.out.println("USB打开了");}@Overridepublic void close() {System.out.println("USB关闭了");}};usb.open();usb.close();}
}

抽象方法创建实现类对象调用抽象方法合二为一:

6.总结

1.什么时候使用匿名内部类?

        当简单调用一次接口中的方法,我们就可以使用匿名内部类

2.将一种格式代表实现类对象或者子类对象来学习
3.匿名内部类会编译生成的,我们只需要利用讲的格式去new对象,调用重写的方法即可

7.匿名内部类的复杂使用_当参数传递

        接口

java">public interface USB {// 定义一个抽象方法void open();
}

        测试类

java">public class Demo143StaticInnerClass10 {public static void main(String[] args) {method01(new USB() {@Overridepublic void open() {System.out.println("USB打开了");}});}public static void method01(USB usb){usb.open();}
}

        实现流程

8.匿名内部类的复杂使用_当返回值返回

        接口

java">public interface USB {// 定义一个抽象方法void open();
}

        测试类

java">public class Demo144StaticInnerClass11 {public static void main(String[] args) {USB usb = method01();usb.open();}public static USB method01(){return new USB() {@Overridepublic void open() {System.out.println("USB打开了");}};}
}

实现流程

五、总结

1.权限修饰符

        ①属性:用 private -> 封装思想

        ②成员方法:用 public -> 便于调用

        ③构造public:便于new对象

2.final关键字

        ①修饰类

                a、格式:public final class 类名

                b、特点:不能被继承

        ②修饰方法

                a、格式:修饰符final 返回值类型 方法名(形参){}

                b、特点:不能被重写

                c、注意:final和abstract不可以同时使用

        ③修饰局部变量

                a、格式:final 数据类型 变量名 = 值

                b、特点:不能二次赋值     

        ④修饰对象

                a、格式:final 类型 对象名 = new 对象()

                b、特点: 地址值不能变,但是对象中的属性值可以改变

        ⑤修饰成员变量

                a、格式:final 数据类型 变量名 = 值

                b、特点:需要手动赋值,不能二次赋值

3.代码块

        ①构造代码块

                a、格式:        { 代码 }

                b、执行特点:优先于构造方法执行,每new一次就执行一次

        ②静态代码块

                a、格式:        static{ 代码 }

                b、执行特点:优先于构造代码块和构造方法执行,且只执行一次

4.内部类

        ①静态成员内部类

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

        ②非静态成员内部类

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

        ③局部内部类

                ⭐ 匿名内部类

                        格式1:

                                new 接口/抽象类(){

                                        重写方法

                                }.重写的方法():

       

                        格式2:

                                类名 对象名 = new 接口/抽象类(){

                                        重写方法

                                }

                                对象名.重写的方法

                        注意:

                                学习:一个格式代表实现类对象或者子类对象


http://www.ppmy.cn/news/1443948.html

相关文章

【C++】C++11 的 auto 和 decltype 两个关键字的应用

auto 和 decltype 是 C11 引入的两个关键字,它们增强了类型推导机制,使得代码更加简洁、灵活且易于维护。下面是对这两个关键字的说明以及使用案例。 1. auto auto 关键字允许编译器根据初始化表达式自动推导出变量的类型。这在处理复杂类型或者避免重…

一文解读 SQL 生成工具

SQL 生成工具可用于测试 Parser 与其他数据库产品的兼容性,通过解析 YACC 语法文件中的产生式,生成对应的 SQL 语句,再使用数据库执行该 SQL,根据结果判断语句是否与其他数据库语法兼容。 01工具使用 语法文件预处理 预处理目的…

JAVA 每日面试题(二)

Java 高级面试问题及答案 1. 什么是Java内存模型(JMM)?它在多线程编程中扮演什么角色? 答案: Java内存模型(JMM)是一个抽象的概念,它定义了Java程序在执行时,变量的访问…

C++初阶-----对运算符重载的进一步理解

1.对于运算符重载的进一步理解 (1)运算符重载就是运算符重新定义的意思,我们如果想要比较两个整形数据的大小,这个是很容易的,但是当我们定义一个类之后,使用这个类创建对象,想要直接比较这两个…

如何在React中实现状态钩子

在React中,状态钩子(State Hooks)主要是用来在函数组件中添加和管理组件状态的。最常用的状态钩子是useState。以下是如何在React中使用useState钩子来实现状态管理的一个简单示例: jsx复制代码 import React, { useState } from…

什么是RabbitMQ,RabbitMQ基本概念,RabbitMQ的使用场景

目录 面试官:什么是RabbitMQ,RabbitMQ的使用场景什么是RabbitMQ?RabbitMQ基本概念RabbitMQ的使用场景举例该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:什么是RabbitMQ,RabbitMQ的使用场景 …

抖音智能运营系统源码

这是一个一站式服务的抖音智能运营系统,旨在提升内容创作者和营销人员的工作效率。它是一个综合性的在线服务平台,专为抖音内容创作者和营销人员设计。系统基于高性能、可扩展性强的ThinkPHP框架,整合了视频处理、数据分析、文案生成与配音等…

Qt [获取Dump] 使用WindowsAPI实现生成MiniDump文件

说明 客户现场的软件偶发崩溃是程序开发者,比较头疼的事情。如何更快速的定位到问题点和解决掉,是开发应该具备的基本能力。 Windows提供了一系列的API,可以记录软件崩溃前的堆栈信息。下面就实现一个生成Dump文件的程序实例。 主要代码 回…