Java学习
2022.4.26
main():public static void main(String[] args){}
jdk : jre + java开发工具集 //适用于程序员开发使用(开发环境)
jre : jvm + java核心库类 //使用于使用者运行(运行环境)
.java : 源文件 .class :字节码文件
.java 源文件里 每一个类都会生成一个class字节码文件
如果源文件中含有public类,贼文件名必须按该类名命名!
非public类也可以使用main方法
2022.4.27
浮点数 = 符号位 + 指数位 + 尾数位
当我们对运算结果的小数的进行相等判断是,要小心(如果是查询得到或直接赋值的变量即可直接判断)
应该是以两个数的差值的绝对值,在某个精度范围类判断(Math.abs(num1 - num2))
字符串型本质:
字符型存储到计算机中,需要将字符对应的码值(整数)找出来,比如'a'
存储 :'a' ---> 97 ---> 二进制数 ---> 机器
读取 :二进制 --> 97 --> 'a' --> 显示
不同的字符编码对文件大小有关系
Unicode: 固定用两个字节表示字符
utf-8: 字母用1个字节,汉字使用3个字节
gbk: 字母用一个字节,汉字用2个字节
gb2312: < gbk
big5 :繁体中文,台湾,香港
ASCII码:一个字节表示256个字符,而ASCII码只用了128个字符就表示完了
自动类型转换:
char --> int --> long --> float --> double
byte --> short --> int --> long -- > float --> double
char 和 (byte、short)不会相互转换
char、byte、short 计算时,首先会转换成int类型
表达式结果的类型自动提升为 操作数中最大的类型
具体数赋值:
会判断具体数是否在数字类型的范围内
变量赋值:
直接判断精度大小
运算符:
是一种特殊的符号,用于数据的运算、赋值和比较等
%(取余)的本质:
a % b = a - a / b * b
复合赋值运算符会进行类型转换
例如:byte b = 3; b += 2; //等价于b = (byte)(b + 2); b++; //等价于b = (byte)(b + 1);
三元运算符细节:
要赋给c的 a 和 b的值的类型一定要是和c相对应的或者可以自动转换的或者自己强转。(三元运算符本质就是if... else...)
int c = a >b ? a : b;
标识符的命名规范
- 包名:都用小写 com.hso.crm
- 类名:大驼峰 :单词首字母全大写 TankShotGame
- 变量名方法名:小驼峰:除首个单词外其他全大写 tankShotGame
- 常量名:所有字母大写,单词之间用_下划线连接。TAX_RATE
break:
可以+标签指定退出哪个循环体
2022.4.28
初始化赋值
int,short,byte,long : 0
float,double:0.0
char:\u0000
boolean:false
String:null
数组
数组传递的是地址,而普通变量传递的是值。
二维数组:先指向存放地址的空间,存放地址的空间再指向存放数据的空间。
二维数组中每一个一维数组的大小可以不一样。
类和对象的内存分布:
对象在栈中存一个地址,地址指向堆中的对象属性,每个属性根据数据类型不同存放的数据也不同,String为引用类型,存放地址,地址指向方法区的常量池,在常量池中存放数据。
java创建对象的流程:
- 先加载相关类的信息(属性和方法信息,只加载一次)
- 在堆中分配内存空间,并进行默认初始化
- 将堆的内存地址分配给对象名,对象名指向对象
- 进行指定的初始化。
java对象方法调用小结:
- 当程序执行到方法时,会在栈内开辟一个新的独立空间(栈空间)
- 当方法执行完毕后或者执行到return语句后,就会返回
- 返回到调用方法的地方同时销毁栈空间
- 返回后,继续执行方法后面的代码
- 当main方法(栈)执行完毕后,整个程序退出
类和对象的内存分配机制:
- 栈:一般存放基本数据类型(局部变量)
- 堆:存放对象和数组
- 方法区:常量池(常量,比如字符串),类加载信息(属性和方法)
形参列表:
- 一个方法可以有0个参数,也可以有多个参数。
- 参数类型可以为任意类型,包含基本类型和引用类型
- 调用带参数的方法时,一定对应着参数列表传入相同类型或兼容类型的参数。
- 方法定义的参数为形参;方法调用时的参数称为实参。形参和实参的类型要一直
2022.4.29
可变参数:
用于解决多个同名同功能但是参数不同的方法的冗余。
方法:
int... nums :int类型的可变参数 nums 最后 nums本质就是数组
细节:
- 可变参数的实参可以为0个或任意多个
- 可变参数的类型可以为数组
- 可变参数的本质是数组
- 可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后
- 一个形参列表中只能出现一个可变参数(4和5某种情况下是相互对应的)
作用域:
- 属性和局部变量可以重名,访问时遵循就近原则。
- 在同一个作用域中,比如在同一个成员方法中,两个局部变量,不能重名。
- 属性随着对象的创建而创建,伴随着对象的死亡而死亡。局部变量随着它的代码块的创建而创建,伴随着代码块的死亡而死亡。
- 作用域范围:全局变量/属性:可以被本类使用,或其他类使用。局部变量:只能在本类中对应的方法中使用。
- 修饰符不同
构造方法/构造器:构造器不是创建对象而是初始化对象
- 构造器没有返回值,也不能写void
- 构造器的名称和类名称一致。
- 构造方法也可以重载
- 创建类的同时就会自动生成一个默认构造器
对象创建的流程:
- 加载类信息(类的属性和方法,只加载一次)
- 在堆中分配内存空间(地址)
- 完成对象初始化[默认初始化 —> 显式初始化 —> 构造器初始化]
- 在对象在堆中的地址,返回给对象名
this:
java虚拟机会给每个对象分配this, 代表当前对象。
2022.4.30
面对对象编程的三大特征:
- 封装
- 继承
- 多态
封装:
封装介绍:
把属性和方法封装在一起,数据被保护在内部,程序的其他部分只有通过被授权的操作,才能对数据进行操作。
封装的好处:
- 隐藏实现细节
- 可以对数据进行验证,保证安全合理
封装的实现步骤
- 将属性进行私有化private
- 提供一个公共的set方法,用于对属性判断并赋值
- 提供一个公共的get方法,用于获取属性的值
继承
继承的介绍:
当多个类存在相同的属性和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法。
基本语法
class 子类 extends 父类{
}
- 子类会自动拥有父类定义的不是private私有属性的对象属性和对象方法。
- 父类又叫超类,基类。
- 子类又教派生类。
继承的好处:
- 代码的复用性提高了
- 代码的扩展性和维护性提高了
继承的细节:
- 子类必须调用父类的构造器,完成父类的初始化
- 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参数构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用super去指定使用父类的哪个构造器去完成父类的初始化工作,否则,编译无法通过。
- 如果希望指定去调用父类的哪个构造器,则显式的调用一下:super(参数列表)
- super()在使用时,必须放在构造器的第一列
- super()和this()都只能放在构造器的第一行,因此两个方法不能共存在同一个构造器中
- java所有类都是Object类的子类,Object是所有类的父类
- 父类构造器的调用不限于直接父类!将一直往上追溯直到Object类(顶级父类)
- JAVA的类是单继承
- 不能滥用继承,子类和父类必须满足 is-a 的逻辑关系
继承的本质分析
- 加载类的信息(属性和方法),从顶级父类开始加载
- 在堆中分配对象的空间
- 在空间中分配父类和子类的相关属性
继承的属性访问
首先看子类是否有该属性
若子类有该属性且该属性可以访问(不是 private 的修饰属性),则返回信息
如果子类没有改属性,就看父类是否有该属性且该属性可以访问,则返回父类的信息
如果父类没有,就按照 3 的规则,继续向上寻找父类,直到Object
如果Object类也没有,则报错。
感觉类似于对象方法的就近原则,如果父有该属性但是属性无法访问,那就直接报错。
super关键字
super基本介绍
super代表父类的引用,用于访问父类的属性、方法、构造器
super基本语法
- 访问父类的属性,但不能访问父类的private属性:super.属性名;
- 访问父类的方法,单不能访问父类的private方法:super.方法名
(参数列表); - 访问父类的构造器:super(参数列表);只能放在构造器的第一句,且只能出现一句!
super给编程带来的便利/好处
调用父类的构造器的好处(分工明确,父类属性由父类初始化,子类的属性由子类初始化)
当子类中有和父类中的成员(属性和方法)重名时,为了访问父类的成员,必须通过super。如果没有重名,使用super、this、直接访问是一样的效果!
就近原则!
super和this的比较
No. | 区别点 | thie | super |
---|---|---|---|
1 | 访问属性 | 访问本类的属性,如果本类没有此属性则从父类中继续查找 | 访问父类的属性 |
2 | 调用方法 | 访问本类的方法,如果本类没有此方法则从父类继续查找 | 直接访问父类中的方法 |
3 | 调用构造器 | 调用本类构造器,必须放在构造器的首行 | 调用父类构造器,必须放在子构造器的首行 |
4 | 特殊 | 表示当前对象 | 子类中访问父类对象 |
方法重写(override)
基本介绍
方法覆盖就是子类有一个方法,和父类的某个方法的名称、返回类型、参数一样,那么我们就说子类的这个方法覆盖了父类(不仅仅是直系)的那个方法
方法重写细节
- 子类的的方法的参数、方法名称,要和父类的方法的参数、方法名称完全一样
- 子类方法的返回类型和父类方法返回类型一样,或者是父类返回类型的子类
- 父类 返回类型是Object, 子类 返回类型是String
- 子类方法不能缩小父类方法的访问权限
- Public > protected > 默认 > private
- void sayOK(){} public void sayOK(){}
方法重写和方法重载的比较
名称 | 发生范围 | 方法名 | 参数列表 | 返回类型 | 修饰符 |
---|---|---|---|---|---|
重载 | 本类 | 必须一样 | 类型、个数、顺序至少有一个不同 | 无要求 | 无要求 |
重写 | 父子类 | 必须一样 | 相同 | 子类重写的返回类型,和父类一致,或者是父类返回类型的子类 | 子类方法不能缩小父类方法的访问范围 |
多态
多态的介绍
方法或对象具有多种形态
方法的多态
重写和重载就体现多态
对象的多态(核心)
一个对象的编译类型和运行类型可以不一致
编译类型在定义对象时,就确定了,不能改变
运行类型是可以变化的
编译类型看定义时 = 号的左边,运行类型看 = 号的右边
父类可以指向子类
多态的细节
前提:两个对象(类)存在继承关系
多态的向上转型
本质:父类的引用指向了子类的对象
语法:父类类型 引用名 = new 子类类型()
特点:编译类型看左边,运行类型看右边。可以调用父类中的所有成员(需要遵循访问规则),不能调用子类中的特有成员
最终运行效果看子类的具体实现。即调研方法时,按照从子类(运行类型)开始查找方法,然后开始调用。
因为在编译阶段,能调用哪些成员,是由编译类型来决定的
多态的向下转型
- 语法:子类类型 引用名 = (子类类型) 父类引用;
- 只能强制转父类的引用,不能强转父类的对象
- 要求父类的引用必须指向的是当前目标类型的对象
- 当向下转型时,可以调用子类类型的所有成员
多态注意事项和细节讨论
- 属性没有重写之说!属性的值看编译类型
- instanceOf 比较操作符, 用于判断对象的类型是否为XX类型或XX类型的子类型
java的动态绑定机制
- 当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定
- 当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用
多态的应用
1) 多态数组
Person[] persons = new Person[5];
persons[0] = new Person;
persons[1] = new Student;
2) 多态参数
Object类详解
1) equals方法
== 和 equals的对比
- == :既可以判断基本类型,又可以判断引用类型
- == :如果判断基本类型,判断的是值是否相等
- == :如果判断引用类型,判断的是地址是否相等,即判定是不是同一个对象
- equals :是Object类中的方法,只能判断引用类型,如何查看Jdk源码
- equals :默认判断的是地址是否相等,子类中往往重写该方法,用于判断内容是否相等。
2) hashCode方法
hashCOde小结
- 提高具有哈希结构的容器的效率
- 两个引用,如果指向的是同一个对象,则哈希值肯定是一样的
- 两个引用,如果指向的不是同一个对象,则哈希值是不一样的
- 哈希值主要根据地址号来!,不能完全将哈希值等价于地址
3) toString方法
基本介绍
默认返回:全类名 + @ + 哈希值的十六进制
重写toString方法,打印对象或拼接对象时,都会自动调用该对象的toString形式
当直接输出一个对象时,toString方法会被默认的调用
alt + insert 快捷键重写即可
4) finalize方法
当对象被回收时,系统懂调用该对象的finalize方法。子类可以重写该方法,做一些释放资源的操作
什么时候被回收:当某个对象没有任务引用时,则jvm就认为这个对象是一个垃圾对象,就会使用垃圾回收机制来销毁该对象,在销毁该对象前,会先调用finalize()方法
Person person = new Person(); person = null; 此时Person对象就是垃圾对象。因为没人去指向它,没有被引用,此时垃圾回收期就会回收对象。 在销毁和回收该对象时,会调用该对象的finalize()方法, 因此程序员可以在finalize中,写自己的业务逻辑代码(比如释放资源,数据库连接,或者打开文件...) 如果程序员不重写finalize,那么就会调用Object类的 finalize,即默认处理 如果程序员重写了finalize,就可以实现自己的逻辑
垃圾回收机制的调用,是由系统来决定,也可以通过System.gc()主动触发垃圾回收机制。
断点调试
一个实际需求
- 在开发中,新手程序员在查找错误时,此时老程序员就会温馨提示,可以用断点调试,一步一步的看源码执行的过程,从而发现错误所在。
- 重要提示:在断点调试过程中,是运行状态,是以对象的运行类型来执行的
断点调试介绍
- 断点调试是指在程序的某一行设置一个断点,调试时,程序运行到这一行就会停住,然后你可以一步一步往下调试,调试过程中可以看各个变量当前的值,出错的话,调试到出错的代码行即显示错误,停下。进行分析从而找到这个BUG
- 断点调试是程序员必须掌握的技能
- 断点调试也能帮助我们查看java底层源代码的执行过程,提高程序员的java水平
断点调试的快捷键
- F7(跳入)
- F8(跳过)
- shift + F8(跳出)
- F9(resume,执行到下一个断点)
2022.5.1
访问修饰符
本类 | 同包 | 子类 | 不同包 | |
---|---|---|---|---|
Public | √ | √ | √ | √ |
Protected | √ | √ | √ | × |
默认 | √ | √ | × | × |
Private | √ | × | × | × |
类变量
static变量
- static类变量是同一个类所有对象共享
- static类变量,在类加载的时候就生成了
介绍
类变量也叫静态变量/静态属性,是该类的所有对象共享的变量,任何一个该类的对象去访问它时,取到的都是同一个值,同样任何一个该类的对象去修改它时,修改的也是同一个变量。
语法
访问修饰符 static 数据类型 变量名;[推荐]
static 访问修饰符 数据类型 变量名;
如何访问
类名.类变量名/对象名.类变量名[推荐]
细节
1).什么时候需要用类变量
当我们需要让某个类的所有对象共享一个变量时,就可以考虑使用类变量(静态变量):比如:定义学生类,统计所有学生共交多少钱。
2).类变量与实例变量区别
类变量是该类的所有对象共享的,而实例变量是每个对象独享的。
3).加上static称为类变量或静态变量,否则称为实例变量/普通变量/非静态变量
4).类变量可以通过 类名.类变量名 或者 对象名.类变量名 来访问,但java设计者推荐我们室友 类名.类变量名方式来访问。[前提是 满足访问修饰符的访问权限和范围]
类方法
类方法经典的使用场景
当方法不涉及任何对象相关的成员,而且我们只想把这个方法当成工具,则可以将该方法设计成静态方法,提高开发效率。
小结
在程序员实际开发,往往会将一些通用的方法,设计成静态方法,这样我们不需要创建对象就可以使用了,比如打印一维数组,冒泡排序,完成某个计算任务等..[举例说明...]
类变量和类方法与普通变量和方法的异同
都是随着类的加载而加载,将结构信息存储在方法区 | 有this的参数 | 通过类名调用 | 通过对象名的调用 | 使用与对象有关的关键字(super和this) | 能访问静态变量/静态方法 | 能访问非静态变量/非静态方法 | |
---|---|---|---|---|---|---|---|
类方法 | √ | × | √ | √ | × | √ | × |
普通方法 | √ | √ | × | √ | √ | √ | √ |
静态变量,只能访问静态的成员,非静态的方法,可以 访问静态成员和非静态成员
理解main方法语法
- main方法是jvm调用的
- java虚拟机需要调用类的main()方法,所以该方法的访问权限必须是public
- jvm在执行main()方法时,不必创建对象,所以该方法必须是static
- 该方法接收String类型的数组参数,该数组中保存执行java命令时传递给所运行的参数
- java 执行的程序 参数1 参数2 参数3
main特别提示
- 在main()方法中,我们可以直接调用main方法所在类的静态方法或静态属性
- 但是,不能直接访问该类中的非静态类成员,必须创建该类的一个实例对象后,才能通过这个对象去访问类中的非静态成员
代码块
代码块的基本介绍
代码化块又称为初始化块,属于类中的成员[即 是类的一部分],类似于方法,将逻辑语句封装在方法块中,通过{}包围起来。
但和方法不同,没有方法名,没有返回,没有参数,只有方法体,而且不用通过对象或类显式调用,而是加载类时,或创建对象时隐式调用
基本语法
[修饰符]{
代码
};
注意:
修饰符 可选,要写的话,也只能写 static
代码块分为两类,使用static修饰的叫静态代码块,没有static修饰的,叫普通代码块。
逻辑语句可以为任何逻辑语句(输入、输出、方法调用、循环、判断等)
;号可以写上,也可以省略。
无论调用哪个构造器,创建对象,都会先调用代码块的内容 代码块调用的顺序优于构造器
代码块细节
static代码块也叫静态代码块,作用就是对类进行初始化,而且它随着类的加载而执行,而且只会执行一次。如果是普通代码块,每创建一个对象,就执行。
类什么时候被加载[重要!]
- 创建对象实例时(new)
- 创建子类对象实例,父类也会被加载
- 使用类的静态成员时(静态属性,静态方法)
普通的代码块,在创建对象实例时,会被隐式的调用。被创建一次,就会调用一次。
如果只是使用类的静态成员时,普通代码块并不会被执行。 小结: 1. static代码块是类加载时,普通代码块并不会执行。 2. 普通代码块是在创建对象时调用的,创建一次,调用一次。 3. 类加载的三种情况,需要记住。
创建一个对象时,在一个类 调用顺序是:(重点,难点):
- 调用静态代码块和静态属性初始化(注意:静态代码块和静态属性初始化调用的优先级一样,如果有多个静态代码块和多个静态变量初始化,则按他们定义的顺序调用)
- 调用普通代码块和普通属性的初始化(主义:普通代码块和普通属性初始化调用的优先级一样,如果有多个普通代码块和多个普通属性初始化,则按定义顺序调用)
- 调用构造方法
构造器的最前面骑士隐含了super()和调用普通代码块
创建一个子类对象时,他们的静态代码块,静态属性初始化,普通代码块,普通属性初始化,构造方法的调用顺序如下:
- 父类的静态代码块和静态属性(优先级一样,按定义顺序执行)
- 子类的静态代码块和静态属性(优先级一样,按定义顺序执行)
- 父类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)
- 父类的构造方法
- 子类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)
- 子类的构造方法
静态代码块只能直接调用静态成员,普通代码块可以调用任意成员。
设计模式
介绍
静态方法和属性的经典实用
设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格以及解决问题的思考方式。设计模式就像是经典的棋谱,不同的棋局,我们用不同的棋谱,免去我们自己再思考和摸索
其实就是套路
单例模式
介绍
- 所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法
- 单例模式有两种方式:1)饿汉式 2)懒汉式
饿汉式
步骤
- 构造器私有化 —> 防止直接New
- 类的内部创建对象
- 向外暴露一个静态的公共方法
- 代码实现
懒汉式
步骤
- 构造器私有化 —> 防止直接New
- 类的内部创建对象
- 向外暴露一个静态的公共方法
- 代码实现
饿汉式 VS 懒汉式
- 二者最主要的区别在于创建对象的时机不同:饿汉式是在类加载就创建了对象实例,而懒汉式是在使用时才创建
- 饿汉式不存在线程安全问题,懒汉式存在线程安全问题
- 饿汉式存在浪费资源的可能。
- 在javaSE标准中,java.lang.Runtime就是经典的单例模式
final修饰符
- 当不希望类被继承时,可以用final修饰
- 当不希望父类的某个方法被子类覆盖/重写时,可以用final关键字修饰
- 当不希望类的某个属性的值被修改,可以用final修饰
- 当不希望某个局部变量被修改,可以用final修饰
细节
- final修饰的属性又叫常量,一般 用 xx_xx_xx 来命名
- final修饰的属性在定义时,必须赋初值,并且以后不能再修改,赋值可以在如下位置之一:
- 定义时:如 public final double TAX_RATE = 0.08;
- 在构造器中
- 在代码块中
- 如果final修饰的属性是静态的,则初始化的位置只能是
- 定义时
- 在静态代码块 不能在构造器中赋值
- final类不能继承,但是可以实例化对象
- 如果类不是final类,但是含有final方法,则该方法虽然不能重写,但是可以被继承
- 一般来说,如果一个类已经是final类了,就没有必要再将方法修饰成final方法
- final不能修饰构造方法
- final 和 static 往往搭配使用,效率更高,不会导致类加载,底层编译器做了优化处理
- 包装类,String也是final类
抽象类
介绍
当父类的一些方法不能确定时,可以用abstract关键字来修饰该方法,这个方法就是抽象方法,用abstract来修饰该类就是抽象类
用abstract关键字来修饰一个类时,这个类就叫抽象类
访问修饰符 abstract 类名{ }
用abstract 关键字来修饰一个方法时,这个方法就是抽象方法
访问修饰符 abstract 返回类型 方法名(参数列表);
抽象类的价值更多作用是在于设计,是设计者设计好后,让子类继承并实现抽象类
细节
- 抽象类不能被实例化
- 抽象类不一定要包含abstract方法。也就是说,抽象类可以没有abstract方法
- 一旦类包含了abstract方法,则这个类必须声明为抽象类。
- abstract 只能修饰类和方法,不能修饰属性和其它的
- 抽象类本质还是类
- 抽象方法不能有主体
- 如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,除非它自己也声明为abstract类
- 抽象方法不能使用private、final 和 static来修饰,因为这些关键字都是和重写相违背的
2022.5.2
接口
介绍
接口就是给出一些没有实现的方法,封装在一起,到某个类要使用的时候,在根据具体情况把这些方法写出来
语法
interface 接口名{
//属性
//方法
}
class 类名 implements 接口{
自己属性;
自己方法;
必须实现的接口的抽象方法;
}
小结
- 在接口中,抽象方法,可以省略abstract关键字
- 在JKD8后,可以有默认实现方法,需要使用default关键字修饰和静态方法
细节
- 接口不能被实例化
- 接口中所有的方法是 public方法,接口中抽象方法,可以不用 abstract 修饰
- 一个普通类实现接口,就要把接口内所有的方法都实现
- 一个类可以同时实现多个接口
- 接口中的属性,只能是final的,而且是public static final修饰符
- 接口中属性的访问形式:接口名.属性名
- 接口不能继承其它的类,但是可以继承多个别的接口
- 接口的修饰符只能是 Public 和 默认
实现接口 VS 继承类
接口和继承解决的问题不同
- 继承的价值主要在于:解决代码的复用性和可维护性
- 接口的价值主要在于:设计,设计好各种规范,让其他类去实现这些方法
接口比继承更加灵活
接口比继承更加灵活,继承是满足 is - a的关系, 而接口只需满足 like - a 的关系
接口在一定程度上实现代码解耦[接口的规范性 + 动态绑定机制]
接口多态
内部类
基本介绍
一个类的内部又完整的嵌套了另一个类结构。被嵌套的类称为内部类,嵌套其他类的类称为外部类。是我们类的第五大成员[属性、方法、代码块、构造器、内部类 ],内部类的最大特点就是可以直接访问私有属性,并且可以体现类与类之间的包含关系。
分类
定义在外部类局部位置上(比如方法内):
局部内部类(有类名)
- 局部内部类是定义在外部类的局部位置,通常在方法(代码块)
- 可以直接访问外部类的所以成员,包含私有的
- 不能添加访问修饰符,但是可以使用final 修饰
- 作用域:仅仅在定义它的方法或代码块中
- 局部内部类可以直接访问外部类的成员
- 外部类需要创建对象实例才可以调用方法
- 如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果要访问外部类的成员,使用外部类名.this.成员) 去访问
匿名内部类(没有类名,重点)
- 本质是类
- 内部类
- 该类没有名字
- 同时还是一个对象
- 细节
- 可以直接访问外部类的所有对象,包括私有的
- 不能添加访问修饰符,因为它的地位就是一个局部变量
- 作用域:仅仅在定义它的方法或代码块中
- 匿名内部类—访问—>外部类成员
- 如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果要访问外部类的成员,使用外部类名.this.成员) 去访问
定义在外部类的成员位置上:
- 成员内部类(没用static修饰)
- 可以直接访问外部类的所有成员,包含私有的
- 可以添加任意的访问修饰符
- 作用域为整个类体
- 外部类使用成员内部类,还是要创建实例
- 外部其他类访问成员内部类
- 通过外部类创建成员内部类实例
- 在外部类中,编写一个返回对象的方法
- 静态内部类(使用static修饰)
- 可以直接访问外部类的所有静态成员,包含私有的
- 可以添加任意的访问修饰符
- 作用域为整个类体
- 如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果要访问外部类的成员,使用外部类名.成员 去访问
- 成员内部类(没用static修饰)
小结 63756243
- 内部类有四种:
- 局部内部类
- 匿名内部类
- 成员内部类
- 静态内部类
枚举
自定义类实现枚举
- 不需要提供setXxx方法,因为枚举对象值通常为只读.
- 对枚举对象/属性使用 final + static 共同修饰,实现底层优化
- 枚举对象名通常使用全部大写,常量的命名规范
- 枚举对象根据需要,也可以有多个属性
enmu 关键字实现枚举
- 使用关键字 enum 替代 class
- public static final Season SPRING = new Season(“春天,”温暖”);
- Spring(“春天”,”温暖”);
- 如果有多个常量(对象),使用,号间隔即可
- 如果使用enum来实现枚举,要求将定义常量对象,写在前面
enum常用方法
- toString:返回的是当前对面名,可重写返回对象的属性信息
- name:返回当前对象名,子类中不能重写
- ordinal:返回当前对面的位置号,默认从0开始
- values:返回当前枚举中所有的常量
- valueOf:将字符串转换成枚举对象,要求字符串必须为已有的常量名
- compareTo:比较两个枚举常量,比较的就是位置号
Annoation
- @interface:表示一个注解类
- @Override:表示指定重写父类的方法/只能用在方法
- @Target:是修饰注解的注解,称为元注解
- @Deprecated 修饰某个元素,表示该元素已经过时/不推荐使用,而不是不能用/可以修饰方法,类,字段,包,参数等等/可以做版本升级过渡
- @SuppressWarings:用来抑制警告信息/在{“”}中,可以写入你希望抑制警告信息
元注解
- Retention //指定注解的作用范围,三只SOURCE
2022.5.3