面向对象(高级)(二)

简介: 面向对象(高级)(二)

4. final关键字


final关键字可以修饰类、属性、方法、局部变量。

使用到final关键字的情况:

🐔 当不希望类被继承:

final class A { } //无法被继承

🐔 当不希望父类的某个方法被子类重写时

🐔 当不希望某个类中某个值被修改

public  final int SIZE = 5 ;

🐔当不希望某个局部变量被修改

final double TAX_RATE = 0.08 ;

注意事项和使用细节:

1. final修饰的属性又叫常量,一般用 XX_XX_XX命名

2. final修饰的属性在定义时必须初始化,可选在如下位置:

(1)如:public  final int SIZE = 5 ;


(2)构造器中;


(3)在代码块中;


3. 如果final修饰的属性是静态的,则被初始化的位置只能是


(1)定义时


(2)在静态代码块中,不能在构造器中赋值,因为实例对象才能调用构造器


4. final类不能被继承,但是可以实例化


5. final不能修饰构造方法


6. final和static往往搭配使用,效率更高,不会导致类加载,底层的编译器进行了优化处理。


5. 内部类

内部类是本章的重难点,在以后看源码的时候,会看见大量的内部类。

基本介绍:当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么这个内部的完整结构最好使用内部类。在 Java 中,可以将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类。内部类也是封装的一种体现。


基本语法:


 class OutClass { //外部类
    class InnerClass{ //内部类
    }
}
class other { //外部其他类
}


特点: 既可以访问私有属性,又可以体现类与类之间的包含关系。


内部类的分类

定义在外部类局部位置上(比如方法内);


(1)局部内部类(有类名)


(2)匿名内部类(没有类名)


定义在外部类的成员位置上:


(1)实例内部类(没有static)


(2)静态内部类(使用static修饰)


1. 局部内部


说明:

1. 可以访问外部类的所有成员;

2. 不能添加访问修饰符,因为它的地位相当与局部变量,但是可以用final修饰

3. 作用域:仅仅只定义在它的方法或者代码段中

4. 在访问成员时直接调用即可

5. 外部类在方法中,可以创建内部类对象,然后调用方法即可;如:


public class Outer {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.n1();
    }
    private int n1 = 100;
    private void m2() {
        System.out.println("2");
    }
    public void n1() {
        final class Inner {
            public void f1() {
                System.out.println("1");
                m2();
            }
        }
        Inner inner = new Inner();
        inner.f1();
    }
}

464c4df006d24fad8664a64a3b779a8d.png


6. 如果外部类和局部内部类成员发生重名时,默认遵守就近原则,如果向想访问外部类的成员,可以使用(外部类名.this.成员名


2. 匿名内部类


本质:

(1)本质仍是一个类

(2)是个内部类

(3)从宏观上来来书评该类没有名字,但是在底层上被赋予了一个名字

(4)同时还是个对象

说明:匿名内部类定义在外部类的局部位置,譬如方法体,但是没有名字

语法:

new 类或者接口(参数列表){
        类体
};

例如:

class Outer {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.method();
    }
    private int m = 10;
    public void method() {
        //需求:使用一个IA接口,并创建一个对象
        //传统写法:写一个类,实现该接口
        IA tiger = new Tiger();
        tiger.cry();
    }
}
interface IA {
    public void cry();
}
class Tiger implements IA {
    @Override
    public void cry() {
       System.out.println("嗷嗷嗷嗷");
    }
}

47aff7cf357e4e4591e752a49a971c72.png

但是如果我只用一次,后面就不再使用,这里单独写一个Tiger时不时太浪费了,所以我们可以试着用匿名内部类写。

class Outer {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.method();
    }
    private int m = 10;
    public void method() {
        //需求:使用一个IA接口,并创建一个对象
        //传统写法:写一个类,实现该接口
        //现在我们不要Tiger类
       IA tiger = new IA() {
            @Override
            public void cry() {
                System.out.println("嗷嗷嗷嗷");
            }
        };
       tiger.cry();
    }
}
interface IA {
    public void cry();
}


70a532e7bf5d4499a3dcca0d7549783d.png


本来我们的接口是不可以直接实例化对象的,但这里就相当于重写了cry()方法,并没有实例化它的对象。

class Outer {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.method();
    }
    private int m = 10;
    public void method() {
        //需求:使用一个IA接口,并创建一个对象
        //传统写法:写一个类,实现该接口
        //现在我们不要Tiger类
        //使用匿名内部类来简化代码
        //此时的编译类型是:IA接口
        //此时的运行类型是:匿名内部类
        /*
            底层:
            class XXXXXXX(类名) implements IA {
            @Override
            public void cry() {
                System.out.println("嗷嗷嗷嗷");
            }
        };
         */
       IA tiger = new IA() {
            @Override
            public void cry() {
                System.out.println("嗷嗷嗷嗷");
            }
        };
       tiger.cry();
    }
}
interface IA {
    public void cry();
}


f75288d8fdf34d8faddd34e46ce0b7df.png


现在我们来看看它在底层中具体的名字:


System.out.println(tiger.getClass());我们用getClass()方法来获取名字。


0e4b1115f04747cabd35297b772ed6b4.png


它的名字就是: class 包名.外部类名$1

匿名内部类的使用细节:

1.匿名内部类既是一个类的定义,又是一个对象;从语法上看它既有类的特性又有对象的特征。

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

3. 不可以添加修饰符,因为他就是个局部变量

4. 作用域仅仅在定义它的方法或代码块中

5.外部类不可以访问匿名内部类(因为他是个局部变量)

6.如果外部类和局部内部类成员发生重名时,默认遵守就近原则,如果向想访问外部类的成员,可以使用(外部类名.this.成员名


实例内部类


在外部类中,内部类定义位置与外部类成员所处的位置相同,因此称为成员内部类

即未被static修饰的成员内部类

说明:

1. 可以访问外部类的所有成员,包括私有的。

例:

public class Main {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.T();
    }
}
class Outer {
    private int n1 = 10;
    class Inner {
        public void say() {
            System.out.println("Outer 中的 n1 = " + n1);
        }
    }
    public void T(){
        Inner inner = new Inner();
        inner.say();
    }
}


只能通过这种方式访问。


801d59ffb9ec40bca47c0503f6725e88.png


2. 实例内部类所处的位置与外部类成员位置相同,因此也受public、private等访问限定符的约束

3. 在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:【外部类名称.this.同名成员 来访问】

4. 实例内部类对象必须在先有外部类对象前提下才能创建

5. 实例内部类的非静态方法中包含了一个指向外部类对象的引用

6. 外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象。


静态内部类

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

public class Main {
    public static void main(String[] args) {
        // 静态内部类对象创建 & 成员访问
        OutClass.InnerClass innerClass = new OutClass.InnerClass();
        innerClass.methodInner();
    }
}
class OutClass {
    private int a;
    static int b;
    public void methodA() {
        a = 10;
        System.out.println(a);
    }
    public static void methodB() {
        System.out.println(b);
    } // 静态内部类:被static修饰的成员内部类
    static class InnerClass {
        public void methodInner() {
        // 在内部类中只能访问外部类的静态成员
        // a = 100; // 编译失败,因为a不是类成员变量
            b = 200;
        // methodA(); // 编译失败,因为methodB()不是类成员方法
            methodB();
        }
    }
}



【注意事项】

1. 在静态内部类中只能访问外部类中的静态成员

2. 创建静态内部类对象时,不需要先创建外部类对象

3.作用域:同其他成员,为整个类体

4.如果外部类和局部内部类成员发生重名时,默认遵守就近原则,如果向想访问外部类的成员,可以使用(外部类名.成员名

相关文章
|
14天前
|
人工智能 自然语言处理 Shell
🦞 如何在 OpenClaw (Clawdbot/Moltbot) 配置阿里云百炼 API
本教程指导用户在开源AI助手Clawdbot中集成阿里云百炼API,涵盖安装Clawdbot、获取百炼API Key、配置环境变量与模型参数、验证调用等完整流程,支持Qwen3-max thinking (Qwen3-Max-2026-01-23)/Qwen - Plus等主流模型,助力本地化智能自动化。
28037 100
🦞 如何在 OpenClaw (Clawdbot/Moltbot) 配置阿里云百炼 API
|
9天前
|
人工智能 安全 机器人
OpenClaw(原 Clawdbot)钉钉对接保姆级教程 手把手教你打造自己的 AI 助手
OpenClaw(原Clawdbot)是一款开源本地AI助手,支持钉钉、飞书等多平台接入。本教程手把手指导Linux下部署与钉钉机器人对接,涵盖环境配置、模型选择(如Qwen)、权限设置及调试,助你快速打造私有、安全、高权限的专属AI助理。(239字)
5358 15
OpenClaw(原 Clawdbot)钉钉对接保姆级教程 手把手教你打造自己的 AI 助手
|
8天前
|
人工智能 机器人 Linux
OpenClaw(Clawdbot、Moltbot)汉化版部署教程指南(零门槛)
OpenClaw作为2026年GitHub上增长最快的开源项目之一,一周内Stars从7800飙升至12万+,其核心优势在于打破传统聊天机器人的局限,能真正执行读写文件、运行脚本、浏览器自动化等实操任务。但原版全英文界面对中文用户存在上手门槛,汉化版通过覆盖命令行(CLI)与网页控制台(Dashboard)核心模块,解决了语言障碍,同时保持与官方版本的实时同步,确保新功能最快1小时内可用。本文将详细拆解汉化版OpenClaw的搭建流程,涵盖本地安装、Docker部署、服务器远程访问等场景,同时提供环境适配、问题排查与国内应用集成方案,助力中文用户高效搭建专属AI助手。
3886 8
|
10天前
|
人工智能 机器人 Linux
保姆级 OpenClaw (原 Clawdbot)飞书对接教程 手把手教你搭建 AI 助手
OpenClaw(原Clawdbot)是一款开源本地AI智能体,支持飞书等多平台对接。本教程手把手教你Linux下部署,实现数据私有、系统控制、网页浏览与代码编写,全程保姆级操作,240字内搞定专属AI助手搭建!
5084 17
保姆级 OpenClaw (原 Clawdbot)飞书对接教程 手把手教你搭建 AI 助手
|
3天前
|
应用服务中间件 API 网络安全
3分钟汉化OpenClaw,使用Docker快速部署启动OpenClaw(Clawdbot)教程
2026年全新推出的OpenClaw汉化版,是基于Claude API开发的智能对话系统本土化优化版本,解决了原版英文界面的使用壁垒,实现了界面、文档、指令的全中文适配。该版本采用Docker容器化部署方案,开箱即用,支持Linux、macOS、Windows全平台运行,适配个人、企业、生产等多种使用场景,同时具备灵活的配置选项和强大的扩展能力。本文将从项目简介、部署前准备、快速部署、详细配置、问题排查、监控维护等方面,提供完整的部署与使用指南,文中包含实操代码命令,确保不同技术水平的用户都能快速落地使用。
2493 0
|
10天前
|
存储 人工智能 机器人
OpenClaw是什么?阿里云OpenClaw(原Clawdbot/Moltbot)一键部署官方教程参考
OpenClaw是什么?OpenClaw(原Clawdbot/Moltbot)是一款实用的个人AI助理,能够24小时响应指令并执行任务,如处理文件、查询信息、自动化协同等。阿里云推出的OpenClaw一键部署方案,简化了复杂配置流程,用户无需专业技术储备,即可快速在轻量应用服务器上启用该服务,打造专属AI助理。本文将详细拆解部署全流程、进阶功能配置及常见问题解决方案,确保不改变原意且无营销表述。
5514 5
|
12天前
|
人工智能 JavaScript 应用服务中间件
零门槛部署本地AI助手:Windows系统Moltbot(Clawdbot)保姆级教程
Moltbot(原Clawdbot)是一款功能全面的智能体AI助手,不仅能通过聊天互动响应需求,还具备“动手”和“跑腿”能力——“手”可读写本地文件、执行代码、操控命令行,“脚”能联网搜索、访问网页并分析内容,“大脑”则可接入Qwen、OpenAI等云端API,或利用本地GPU运行模型。本教程专为Windows系统用户打造,从环境搭建到问题排查,详细拆解全流程,即使无技术基础也能顺利部署本地AI助理。
7431 16
|
12天前
|
人工智能 JavaScript API
零门槛部署本地 AI 助手:Clawdbot/Meltbot 部署深度保姆级教程
Clawdbot(Moltbot)是一款智能体AI助手,具备“手”(读写文件、执行代码)、“脚”(联网搜索、分析网页)和“脑”(接入Qwen/OpenAI等API或本地GPU模型)。本指南详解Windows下从Node.js环境搭建、一键安装到Token配置的全流程,助你快速部署本地AI助理。(239字)
5057 22