1. 概述
-
每一个应用程序都以类名开头 ,类名必须与文件名匹配,所以保存文件时,要使用类名保存;
-
java中运行的每一行代码都必须在一个
class
中; -
在类名的开头,可以用权限修饰符来解释,如
private
或者public
; -
main()
方法是必需的,每一个Java程序都有; -
main()
方法中的任何代码都会被执行; -
对于
xxx
类中的main()
方法中的方法(函数
),相当于嵌套调用; -
可以使用
println()
方法将一行文本打印到屏幕上,如:javapublic static void main(String[] args) { System.out.println("Hello World"); }
-
同样,与c++一致,大括号表示代码块的开始和结束;
-
每个代码语句必须用分号结尾;
2. 注释
- 单行注释以
//
开头,java将默认忽略//
和行尾之间的任何文本; - 多行注释以
/*
开头,*/
结尾,同样两者之间的文本会被Java忽略;
3. 变量类型
-
变量是存储数据的容器;
-
Java的变量类型有:
string
:文本,字符串;int
:有符号数;float
:浮点数;char
:存储单个字符,通过"......"
的形式接收,当然'......'
也行;boolean
:存储布尔值,有true
和false
两种;
-
建立变量:
-
指定类型 (+ 赋值);
type variable (= value)
; -
一般情况下,新的赋值会覆盖掉旧的赋值,如果要避免这种情况,可以使用
final
关键字声明在变量定义前面,如:javafinal int num=1;
这样会将变量设置为只读不可写;
-
-
我们可以使用
System.out.println()
的方式用于显示变量; -
如果要一次性声明多个同样类型的变量,可以用
,
隔开,如int i1=1,i2=2;
-
java的变量名不应包含空格;
-
理论上可以使用
$
和_
开头; -
java的名称区分大小写;
-
system默认的关键字不要用做变量名,不然会覆盖掉原有设置好的;
4. 数据类型
- 基本数据类型
byte
,short
之类的; - 非基本数据类型
String
,Arrays
和Classes
;
-
基本八种:
数据类型 大小 描述 byte 1B 有符号二进制数 short 2B 范围小有符号数 int 4B 范围适中的有符号数 long 8B 范围较大的有符号数 float 4B 范围适中的浮点数 double 8B 范围较大的浮点数 boolean 1b,即一位 存储 true
和false
char 2B 存储单个字符 -
对对应数据类型赋值时,应当在数值末尾加上对应的类型符,如
long---L
,float---f
,double---d
; -
boolean型的取值只能是
true
或者false
; -
浮点数用
e
表示10的幂,如12e9=12*10^9
; -
字符的要求,赋值时推荐:字符用单引号,字符串用双引号 ; 注意,字符串的string要写成大写的String,而且它不是原始数据类型,因为使用它的时候需要引用到一个对象;
-
创建的原始类型始终会有数值,而非原始类型则可以以
null
填充; -
原始类型的大小取决于数据类型,而非原属类型的大小都是相同的(
相对固定
);
5. 数据类型转换
- 隐式类型转换
- 自动完成,思路是:通过以零补位的形式实现;
byte-->short-->char-->int-->long-->float-->double
;
- 强制类型转换
- 手动完成,需要强制转换符
(......)
如:int myInt = (int)myDouble;
- 顺序与上边相反的,将较小的类型转换为较小的类型,需要使用强制转换;
- 手动完成,需要强制转换符
6. 运算符
- 用于对变量和值执行操作;
- 包括:
- 算术运算符;
- 赋值运算符;
- 关系运算符;
- 逻辑运算符;
- 位运算符;
%
取模;++
自加1,--
自减1;+=
自加,-=
自减,/=
自除,|=
位或运算,^=
异或运算,&=
位并运算,>>=无符号部分右移得到移码
,无符号部分左移得到移码
;==
等于,!=
不等于;&&
逻辑与、||
逻辑或、!
逻辑非;&
位交,|
位并,~
位取反,^
位异或,<<
左移码,>>
右移码,>>>
右移码并补零;
7. 字符串
- 用字符串结构
String
来存储文本,用双引号包围的字符来传值; - 关于字符串有以下几种方法:
- 字符串长度:
.length()
返回; - 大小写转换:
toUpperCase()
将字符串转变成大写,toLowerCase()
将字符串转变成小写; - 查找字符串第一次出现的位置:
indexOf()
返回第一次出现的位置 (学了数据结构的都知道从零开始
); - 串联:用
+
可以连接前后两个字符串、又或者使用<前者>.concat(<后者>)
的方法;
- 字符串长度:
- 特殊字符必须写在引号内,否则Java会误解此字符串的性质,并生成错误。
- 为了避免',",\被系统误以为有实际功能,可以使用反斜杠
\
将特殊字符转换为字符串; - 除此以外,还有一些特殊的转义字符:
\n
:换行;\r
:回车;\t
:制表;\b
:空格;\f
:换页;
注意:如果是一个数字和一个字符串执行
+
操作,则数字部分会被强制转化为字符串进行运算。
- 更多关于字符串的方法在Java 字符串方法参考手册
8. 数学方法(内置)
用
Math
类的方法
max(x,y)
:用于查找x
和y
的最大值;min(x,y)
:用于查找x
和y
的最小值;sqrt(x)
:用于返回x的平方根;abs(x)
:用于返回x的绝对值;random()
:返回一个介于[0.0,1.0)的随机数,至于如果你要0到10^k之间的随机数,可以用上述随机数乘以10^k+1
来获得;
- 其他的数学方法可以在Java 数学方法参考手册 中查询获得;
所有的数学方法都是
static
静态的;
9. 条件语句
-
使用方法基本和C++差不多;
-
以下介绍三元运算符 :
javavariable=(condition)? expressionTrue:expressionFalse;
其中前者的表达式是条件为真使用的,后边是条件为假使用的。
10. 选择语句
-
即
switch......case
型; -
格式为:
javaswitch(expression){ case x: 代码块1; (break;) case y: 代码块2; (break;) ···· (default: 代码块n;) }
-
意思为:
switch
先计算一次;case
将计算的结果和每个case
后的情况进行条件比较。如果符合的话执行后边相关的代码块;break
、default
是可有可无的;
-
中断关键字
- break:停止在块内执行,并跳出所在的程序块;
- default设置默认值兜底;
-
关键点:
expression
必须是整数、字符、字符串、枚举或者是它们的表达式;break
用于跳出switch
语句,没有它会导致继续执行下一个case
代码块。所以通常在每一个case
语句的末尾添加break
;default
少用,建议在处理不期望的输入时使用它。
11. 循环语句
- 基本和c++的一样;
java
for(代码块第一次执行前执行一次;判断代码块是否执行的条件;代码块执行后执行){
代码块
}
-
除此以外,还有
for-each
循环,它专门用于循环在数组Array
中的元素。javaX型数组A=(A1,A2,...); for (X型值i : A){ 代码块 }
典型的有:
javaString[] cars = {"Volvo", "BMW", "Ford", "Mazda"}; for (String i : cars) { System.out.println(i); }
-
break
跳出循环,continue
跳出本轮循环。他们俩常配置着循环语句使用。
12. 数组
-
用方括号定义变量类型并声明数组:
java数组类型[] 数组名;
-
数组赋的值框在大括号
{···}
里。 -
与C++一样,访问元素用索引,索引从0开始;
-
更改数组元素,可以用索引赋值;
-
数组有方法
.length
可以返回数组有多少个元素; -
for
循环常用于遍历数组,不过for-each
可读性更强,更推荐使用; -
可以通过将数组当成一个元素嵌套到新的数组的方式实现多维数组,如{{1,2},{3,4}}且索引方式也是一级一级打开; 对于多维数组的遍历,多个for循环是不错的方法;
13. 方法(函数)
- 由于java所有的文件都是类文件(
有大有小
),所以方法必须在类里边申明。 - 方法使用名称来定义的,后面跟上{代码块};
- 方法的调用通过方法名配合必要的参数;
- 一个方法可以被多次调用;
- 可以在方法名后增加
()
的方式来传递参数,申明时也要标准形参的数据类型,不同参数之间用,
隔开。 - 当参数被传递给方法后,就从形参转化为实参
也就是它被实体化了。 - 在申明方法时,我们会顺便申明返回值的情况。此处可以用返回值的数值类型说明。与C++一样,返回值用
return
传递。如果是不需要返回值,用void
申明;
14. 重载
- 使用方法重载,可以使多个方法拥有相同的名称和不同参数,便于理清思路和展示联系;
- 与其定义两个应该做相同事情的方法,不如直接重载一个;
- 这里就体现java的方法都在类里定义的好处了。重载不需要再像C++一样有特殊的
operator
运算符,直接下边重写就可以了。 - 只要参数的数量或者类型不同,多个方法就可以具有相同的名称。
15. 作用域
- 在Java中,变量只能够在创建的区域内访问,区域称之为作用域;
- 方法内申明的,申明语句后的语句都可以使用;
- 代码块内申明的变量,只能够由大括号之间的代码访问,且在申明后方可使用;
16. 递归
- 对于函数来说,是自己传值给自己,以实现数学上的递归或者说回归,最后企图得到(可能存在的)不动点。
- 为了防止递归没完没了,显然递归函数都必须要有合理的停止条件,即必须要有能够跳出循环的判断条件;
17. OOP/面向对象编程
- 即同时创建包含的数据和函数的对象,以对象为操作和访问的基本逻辑单位;
- 有利于多态,封装和模块化,提供了清晰的结构。
- 体现了局部性原理的思想;
- 类是对象的模板,对象是类的实例;
- 对象将继承类中的所有变量和方法;
18. 类
-
在java的语法中,类始终以大写字母开头,类名应该要与文件名相匹配。
-
与C++一样,类的申明由
class
关键字开始,类的权限则出现在一开头class
的左边。 -
对象的创建:
java类名 对象名 = new 类名(可能的传参);
其中等号的后半部分是为了申明该对象需要分配的物理存储空间;
-
一个类可以创建多个对象。
-
还可以创建一个类的对象并在另一个类中访问它。这有利于更快地组织类(一个类拥有所有的方法和属性(
变量
),另一个类则含有main()
方法;
在命令行中,需要用:
javajavac 对象名.java//编译文件 java 对象名//执行文件
- 对于类中的变量,与C++一直,可以使用
.
取值符来访问,而且可以在新生成的对象中修改它,但只对对象自己有效 。这样看来,类中赋值了的属性,字段或者说变量更像是default默认值一般的存在。 - 如果你不想类中的属性值随意的被对象更改掉,可以在申明的时候添加
final
关键字锁死。
19. 类方法
- 调用格式:
对象名.方法名();
- 经常可以看到具有
static
静态和public
公共属性和方法的Java程序; -
static
:可以在不创建类的对象的情况下访问该方法,例如Math
中的数学计算方法都是static
的就是这个原因;public
:只能用对象来访问方法;
- 为了使用
public
的类方法,我们必须先创建对象再调用。 .
用于访问对象的属性和方法。- 将方法实行和方法建立分散到对应的类和类中的对象中,是很不错的技巧。
20. 构造函数
-
是一种用于初始化对象的特殊方法;
-
在创建类对象的时候会调用构造函数;
-
它常用于设置对象属性的初始值,等于说原来类的属性是没赋值的,现在创建对象的时候再赋值;
-
【注意】:构造函数的名称必须与类名相匹配,且不能有返回值 ,最好直接是
void
; -
但理论上,所有类在创建对象的时候都是有构建函数,只是类中赋值的对象无法设置对象属性的初始值;
-
典型例子:
javapublic class MyClass { int x; public MyClass(int y) { x = y; } public static void main(String[] args) { MyClass myObj = new MyClass(5); System.out.println(myObj.x); } } // 输出 5
21. 修饰符
- 用于设置类、属性、方法和构造函数的访问级别;
- 一般分为两类:
- 访问修饰符 :控制访问级别;
- 非访问修饰符 :不控制访问级别,提供其他功能;
- 对于
class
常用的修饰符有:- 访问修饰符
public
:任何类都可以访问;default
:只能由同一包中的类访问(一般出现在不指定修改器
);
- 非访问修饰符
final
:该类不能被其他类继承(和用在属性上一样,表示不改了
);abstract
:该类被抽象了出来,自身不能创建对象,只能通过继承的方式创建;
- 访问修饰符
- 对于
attribute
或者means
和constructor
来说:- 访问修饰符
public
:所有类都可以访问;private
:只能该类内部访问,即通过类的方法 ,其他类无法直接访问属性(便于实现封装、隐藏内部实现细节,提高代码的安全性和可维护性
);default
:该类只能由同一包中的类进行访问,在不指定修改器时使用;protected
:代码可以在相同包,和子类中访问;
- 非访问修饰符
final
;static
:属性和方法属于类而不是对象;abstract
:只能在抽象类中使用,且只能在方法上使用,即主体部分只能由生成的对象提供。transient
*:序列化 包含属性和方法的对象时,将跳过属性和方法- 在Java中,序列化(Serialization)是指将对象的状态转换为字节流 的过程,从而可以将对象保存到文件、数据库或通过网络传输给其他Java虚拟机(JVM)。反序列化(Deserialization)是将字节流转换回对象的过程。序列化的主要作用是持久化对象状态和对象之间的远程通信。
- 关键点:
- 实现Serializable接口:要使一个Java对象可以序列化,该类必须实现java.io.Serializable接口。
- 序列化过程:使用ObjectOutputStream类的writeObject()方法将对象转换为字节流。
- 反序列化过程:使用ObjectInputStream类的readObject()方法将字节流转换回对象。
- transient关键字:用transient关键字修饰的字段不会被序列化。
volatile
:属性值不是本地缓存的线程,总是从主存中读取- 用于修饰变量,确保在多个线程间对该变量的读写操作的可见性。它的主要作用是保证变量的可见性和防止指令重排序。
主要用途:- 变量的可见性:
- 当一个变量被声明为volatile时,Java内存模型保证所有线程都能看到该变量的最新值。当一个线程修改了volatile变量的值,新值会立即被刷新到主内存中,其他线程读取时可以立即获得最新值。
- 防止指令重排序:
- volatile变量在读取和写入时都会插入内存屏障(memory barrier),这可以防止编译器和处理器对这些操作进行重排序,从而保证了代码执行的顺序一致性。
- 变量的可见性:
- 用于修饰变量,确保在多个线程间对该变量的读写操作的可见性。它的主要作用是保证变量的可见性和防止指令重排序。
- 访问修饰符
22. 封装
- 步骤:
- 将类变量/属性声明为
private
; - 提供公共
get
和set
方法 来访问和更新private
私有变量的值; get
方法返回变量值,set
方法设置值,两者的语法都是以get
或set
开头,后跟变量名,第一个字母大写;
- 将类变量/属性声明为
- 意义:
- 类属性可以设置为只读(
如果只使用get方法
),也可以设置为只写(如果只使用set方法
); - 提高数据的安全性;
- 可以在不影响其他部分的情况下更改代码的一部分;
- 类属性可以设置为只读(
23. 包(package
)
- Java 中的包用于对相关类进行分组。可将其视为文件目录中的文件夹;
- 我们使用包来避免名称冲突,并编写更好的可维护代码。
- 分为两类:
- 内置包(来自Java API的包);
- 用户定义的包(创建自己的包);
API
- Java API 是Java开发环境中包含的一个预编写类库,该库分为包和类,可以免费使用;
- 完整列表可在Oracles网站上找到;
- 该库包含用于管理输入、数据库编程等的组件;
- 要使用库中的类和包,需要使用import关键字;
- 使用
- 导入
- 导入包中的某个类:
import <packagename>.<classname>
,而且要使用导入的类需要创建该类的对象; - 导入整个包:
import <packagename>.*
;
- 导入包中的某个类:
- 创建自己的包
-
使用
package
关键字; -
格式:
javapackage <自定义包名> class <自建类>{......}
-
将上面的文件另存为后编译 ,这将强制编译器创建"自定义包名"的包 -d 关键字指定保存类文件的目标位置,空格后可以直接跟地址也可以直接跟
.
表示在同一目录下(linux
)。 -
要使用创建包中的类,在命令行中使用
java <自定义包名>.<自建类>
;
-
- 导入
24. 继承
- Java 中可以将属性和方法从一个类继承到另一个类。
- 继承分为两部分:
- 子类 (Subclass) - 子,从另一个类继承的类;
- 超类 (Superclass) - 父,被继承的类;
- 要从类继承,请使用
extends
关键字。
总结:访问权限
private
:仅在同一个类可访问;default
(无修饰符):仅在同一个包中可访问;protected
:在同一个包,以及不同包的子类中可以访问;public
:在任何地方都可以访问;
【注意】:protected
成员在子类中可以重写,但在子类外部(即使是子类的实例)不能直接访问这些成员。
- 子类对超类的继承,可以使用
protected
进行安全性的保障,但要注意子类的实例无法使用带该关键字的属性、方法。 - 如果不想其他类从该类继承,同样使用
final
关键字;
25. 多态
- 在子类继承超类时,除默认的超类中的属性、方法外,在代码块中每个子类可以定义属于自己的属性、方法;这种在属性、方法上的差异被解释成多态。
- 也许不同子类的属性、方法名字也叫一样,但是这本质是功能的不同实现,busuanshi"重写";
- 继承和多态的意义:对于代码的可重用性很有用,在创建新类时也可以重用现有类的属性和方法。
26. 内部类/嵌套类
- 即类中类;
- 嵌套类的目的是将属于同一类的类分组,这使代码更具可读性和可维护性;
- 要访问内部类,请创建外部类的对象,然后创建内部类的对象(
一层一层实体化
); - 与常规类不同,常规类的访问关键字只能是
public
或者default
两种,内部类新增加了private
和protected
两种 。如果你想对类设置一些权限,可以采用内部类的方式,甚至直接private
禁止访问。 - 内部类也可以是
static
的,也就是静态的,属于类但不属于对象 ,这意味着可以在不创建外部类的对象的情况下访问它。 但是这与static
静态属性、方法一样,static
的内部类无法访问外部类的属性、方法; - 内部类可以访问外部类的属性和方法;
27. 抽象类
- 数据抽象是隐藏某些细节并仅向用户显示基本信息的过程。
- 可以通过
abstract class
抽象类或interfaces
接口来实现; abstract
关键字是非访问修饰符,用于类和方法:- 抽象类 :不能直接创建对象,只能继承后创建;
- 抽象方法 :只能在抽象类中使用,自身没有主体代码块,主体代码块要继承的子类提供;
- 抽象类中除了抽象方法也存在常规方法;
28. 接口
-
Java 中实现
abstraction
抽象的另一种方法是使用接口,实际上是高度抽象; -
接口,即
interface
关键字定义的部分,是一个完全抽象"类",它将相关方法和空实体分组 ,在接口中所有方法都没有主体代码块; -
要访问接口方式,需要创建一个由
implements
关键字引导"继承的类"。一般情况下,接口的方法在implement类中定义; -
Java中的类只能继承一个父类,但可以实现多个接口,这实现了多重继承的效果。
-
为了实现安全性-隐藏某些细节,只给对象(接口)显示重要细节,例如
api
; -
一些性质的简要说明:
- 接口中的所有方法默认都是抽象的(
即使不加abstract关键字
); - 和抽象类一样,接口不能用于创建对象;
- 接口方法没有主体,主体由
implement
类提供; - 在实现接口时,必须重写其所有方法;
- 接口不能包含构造函数(因为它不能用于创建对象);
- 默认情况下,接口方法是
abstract
抽象的和public
公共的; - I接口属性默认为
public
,static
和final
; - 接口可以包含常量,所有的字段默认是
public static final
的;
- 接口中的所有方法默认都是抽象的(
-
在Java中,接口(interface)是一种引用类型,用于定义一组抽象方法和常量。接口不能包含具体实现,具体的实现由实现接口的类提供。接口在Java中扮演着重要角色,特别是在设计良好的API和实现多重继承时。
28.1 接口的主要特点:
- 抽象方法 :接口中的所有方法默认都是抽象的(即使不加
abstract
关键字),在Java 8之后,可以包含默认方法和静态方法。 - 多重继承:Java中的类只能继承一个父类,但可以实现多个接口,这实现了多重继承的效果。
- 常量 :接口可以包含常量,所有的字段默认是
public static final
的。 - 隐式
public
:接口中的方法默认是public
的,不能是private
或protected
。
28.2 定义和实现接口:
定义接口:
java
public interface Animal {
void eat();
void sleep();
}
实现接口:
java
public class Dog implements Animal {
@Override
public void eat() {
System.out.println("Dog is eating");
}
@Override
public void sleep() {
System.out.println("Dog is sleeping");
}
}
public class Cat implements Animal {
@Override
public void eat() {
System.out.println("Cat is eating");
}
@Override
public void sleep() {
System.out.println("Cat is sleeping");
}
}
28.4 使用接口的优势:
- 多态性:接口可以用于实现多态,一个接口类型的引用可以指向任何实现了该接口的对象。
- 解耦:接口定义了一组方法的集合,具体实现由不同的类提供,这使得代码更加灵活和可维护。
- 代码重用:通过实现接口,不同类可以共享接口的规范,这有助于代码的重用和一致性。
- 分离接口和实现:接口可以定义API规范,而具体实现可以独立开发和变化,这有助于分层设计。
示例:
使用接口实现多态性:
java
public class AnimalFeeder {
public void feed(Animal animal) {
animal.eat();
}
public static void main(String[] args) {
AnimalFeeder feeder = new AnimalFeeder();
Animal dog = new Dog();
Animal cat = new Cat();
feeder.feed(dog); // 输出: Dog is eating
feeder.feed(cat); // 输出: Cat is eating
}
}
28.5 Java 8及之后的接口特性:
- 默认方法 :可以在接口中定义带有默认实现的方法,使用
default
关键字。 - 静态方法 :可以在接口中定义静态方法,使用
static
关键字。 - 私有方法(Java 9及之后):可以在接口中定义私有方法,用于辅助默认方法或静态方法。
示例:
java
public interface Animal {
void eat();
void sleep();
default void breathe() {
System.out.println("Animal is breathing");
}
static void description() {
System.out.println("This is an animal");
}
private void privateMethod() {
// 仅供默认方法或静态方法调用
}
}
28.6 多个接口的实现
- 在
implements
说明之后用,
隔开多个接口名。
28.7 总结
- 接口在Java编程中提供了一种抽象层次,使得代码更加灵活和易于维护。通过理解和应用接口,可以设计出更具扩展性和可维护性的程序。
29. 枚举
-
enum
枚举是一个特殊的"类",它表示一组常量; -
常量指不可更改的变量,如
final
定义下的变量; -
要创建enum,请使用
enum
关键字,并用逗号,
分隔常量; -
【注意】:定义的常量名应该为大写字母;
-
与数组一样,可以使用
.
来访问枚举中的常量; -
可以在类中创建
enum
枚举; -
枚举通常用于
switch
语句中作为case
的比较值检查相应的值; -
枚举类型有一个
values()
方法,该方法返回所有枚举常量的数组 。如果要循环遍历枚举的常量,可以用.values()
先将枚举转化成数组,再使用for-each
方法对其遍历输出/访问即可; -
枚举常量的赋值方式是
常量名{常量的值,......}
,属性的赋值方法是常量名(属性值)
;
29.1 枚举属性和枚举方法
enum
枚举可以像class
一样具有属性和方法。唯一的区别是枚举常量是public static final
;
在Java中,枚举(enum)是一种特殊的类,用于表示一组固定的常量。与普通类不同,枚举的实例是有限且固定的。枚举不仅可以包含常量,还可以包含属性、方法和构造函数,从而使其更加灵活和功能强大。
定义枚举的属性和方法
1. 枚举常量带有属性:
枚举常量可以带有属性,这些属性可以在构造函数中进行初始化。
- 在Java中,枚举常量带有属性时,通常会将这些属性声明为private final并通过构造函数进行初始化,这提供了枚举属性的不可变性和封装的特点。
java
public enum Day {
MONDAY("Start of the work week"),
TUESDAY("Second day"),
WEDNESDAY("Midweek"),
THURSDAY("Almost there"),
FRIDAY("End of the work week"),
SATURDAY("Weekend"),
SUNDAY("Rest day");
private final String description;
// 构造函数
Day(String description) {
this.description = description;
}
// 获取描述的方法
public String getDescription() {
return description;
}
}
在这个示例中,每个枚举常量都带有一个描述属性,并通过构造函数进行初始化。
2. 枚举方法:
枚举还可以包含方法,可以根据需要定义实例方法和静态方法。
java
public enum Operation {
ADDITION("+") {
public double apply(double x, double y) {
return x + y;
}
},
SUBTRACTION("-") {
public double apply(double x, double y) {
return x - y;
}
},
MULTIPLICATION("*") {
public double apply(double x, double y) {
return x * y;
}
},
DIVISION("/") {
public double apply(double x, double y) {
return x / y;
}
};
private final String symbol;
Operation(String symbol) {
this.symbol = symbol;
}
@Override
public String toString() {
return symbol;
}
// 抽象方法,每个枚举实例必须实现此方法
public abstract double apply(double x, double y);
}
在这个示例中,每个枚举常量都表示一个数学运算,并实现了apply
方法。
使用示例:
java
public class EnumTest {
public static void main(String[] args) {
// 使用 Day 枚举
for (Day day : Day.values()) {
System.out.println(day + ": " + day.getDescription());
}
// 使用 Operation 枚举
double x = 10.0;
double y = 5.0;
for (Operation op : Operation.values()) {
System.out.printf("%f %s %f = %f%n", x, op, y, op.apply(x, y));
}
}
}
输出:
MONDAY: Start of the work week
TUESDAY: Second day
WEDNESDAY: Midweek
THURSDAY: Almost there
FRIDAY: End of the work week
SATURDAY: Weekend
SUNDAY: Rest day
10.000000 + 5.000000 = 15.000000
10.000000 - 5.000000 = 5.000000
10.000000 * 5.000000 = 50.000000
10.000000 / 5.000000 = 2.000000
关键点总结:
- 属性:枚举可以包含属性,并通过构造函数初始化。
- 方法:枚举可以包含实例方法和静态方法。
- 抽象方法:枚举可以定义抽象方法,每个枚举常量必须实现该方法。
- 构造函数 :枚举的构造函数总是私有的,可以省略
private
修饰符。
通过这些特性,Java的枚举类型不仅仅是简单的常量集合,还能实现复杂的行为和属性,使其在代码设计中更加灵活和强大。
30. 用户输入
- java采用
scanner
类用于获取用户输入,这个类属于java.util
包中; - 同样,为了使用
scanner
类,需要创建该类的对象,从而使用scanner
类文档中任何可用的方法; - 输入类型与之对应的方法,基本名称就是
next<数据类型,记得开头字母要大写>
:nextBoolean()
:从用户处读取boolean布尔值;nextByte()
:从用户处读取byte字节值;nextDouble()
:从用户处读取double双精度值;- ......
31. 日期和时间
-
与C++不同,Java没有内置的Date类,但是我们可以导入
java.time
包来使用Date
类和time API
; -
java.time
包含的时间和日期类有:LocalDate
:表示日期,格式是年--月--日;LocalTime
:表示时间,格式是小时--分钟--秒钟--纳秒;LocalDateTime
:表示日期和时间;DateTimeFormatter
:格式化显示日期时间;
-
now()
方法可以调出当前的时间数据 ,不同的类都有其自己的now()
方法; -
如果你想让时间按照自己喜欢的格式显示,可以用
DateTimeFormatter
类格式化,并用.offpattern
描述自己需要的格式,并接纳; -
上述描述,小写的
dd
代表日期,大写的若干个M
代表月份,yyyy
象征年份。
32,数组列表
- 在
java.util
包中,包含ArrayList
类,它是一个可以调整大小的数组(array
),或者说C++的向量
、顺序表
; ArrayLis
和Array
最大的区别就是可以改变大小,可以随意增加或者删除元素;
-
生成:
javaimport java.util.ArrayList; // 导入 ArrayList 类 ArrayList<ElemType> <Name> = new ArrayList<ElemType>(); // 创建一个 ArrayList 对象
-
增加:
.add(<值>)
的方法,且增加在末尾; -
查询:
.get位置索引)
的方法; -
修改:
。set(位置索引,值)
的方法; -
删除:
.remove(位置索引)
; -
计算大小:
.size()
的方法; -
遍历:
for
循环 +.size()
方法找到数量大小 /for-each
循环; -
排序:在
java.util
包中,还有一个非常有用的类Collection
。该类中的.sort()
方法可用于按字母或者数字顺序列表的排序,默认是升序。当然除此之外,你还可以传递一个实现了comparator
接口的实例给该方法,以自定义的顺序进行排序,如:javaimport java.util.ArrayList; import java.util.Collections; import java.util.Comparator; public class Main { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<>(); list.add(3); list.add(1); list.add(2); // 自定义排序:降序 Collections.sort(list, new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o2 - o1; // 降序排序 } }); System.out.println(list); // 输出: [3, 2, 1] }
- 需要注意的是,ArrayList中的元素其实是对象,所以要生成对应数据类型的数组列表,使用的是基本类型,如 Integer(int的包装类)、String、Boolean(boolean的包装类)、Character(char的包装类)、Double(double的包装类);
- 非常别扭的是,在自动装箱功能普及的时候,对ArrayList的生成依旧要指定包装类名 ,但在ArrayList以外的代码,包装类名和基本类型基本是通用的。