# 类和对象
Java 作为一种面向对象的语言,支持以下基本概念:多态、继承、封装、抽象、类、对象
实例、方法、重载。
对象:对象是类的一个实例,有状态和行为。
类:类是一个模板,它描述一类对象的行为和状态。
# 创建对象
使用关键字 new 来创建一个新的对象
创建对象步骤说明
A a = new A();
- 声明:声明一个对象,包括对象名称和对象类型。(等号左边)
- 实例化:使用关键字 new 来创建一个对象。
- 初始化:使用 new 创建对象时,会调用构造方法初始化对象。(根据 A () 里面的参数选择构造方法)
# 构造方法
每个类都有构造方法,可以是多个。如果没有显式地为类定义构造方法,Java 编译器将会为该类提供一个默认构造方法(无参的构造方法)。
但是如果已经声明了一个有参的构造方法,那么 Java 编译器就不会给该类提供无参的构造方法了,这时候如果创建对象初始化的时候是使用无参构造方法就会报错
class A{ | |
A(String str){ | |
} | |
} | |
class B{ | |
A a = new A(); | |
// 这样就会报错 | |
} | |
// 所以当一个类已经声明的有参构造方法的时候 | |
// 就需要手动写一个无参构造方法 | |
// 当然,如果用不到无参的构造方法,即可不声明 |
# Java 包
包主要用来对类和接口进行分类。当开发 Java 程序时,可能编写成百上千的类,因此很有必要对类和接口进行分类。
# import 语句
在 Java 中,如果给出一个完整的限定名,包括包名、类名,那么 Java 编译器就可以很容易地定位到源代码或者类。import 语句就是用来提供一个合理的路径,使得编译器可以找到某个类。
import java.util.*; |
package a; | |
class A{ | |
public void sayHi(){ | |
System.out.println("Hi~~~~"); | |
} | |
} | |
// 这时候在同一项目的另一个包里面,我想到调用上面的 A 类下 sayHi()方法 | |
// 如下 | |
package b; | |
import a.A; | |
class B{ | |
A a =new A(); | |
public static void main(String[] agrs){ | |
a.sayHi(); | |
} | |
} | |
// 这样控制台就会输出: | |
// Hi~~~~ |
# 基本数据类型
# 八大基本类型
byte
byte 数据类型是 8 位、有符号的,以二进制补码表示的整数;
最小值是 -128(-2^7);
最大值是 127(2^7-1);
默认值是 0;
byte 类型用在大型数组中节约空间,主要代替整数,因为 byte 变量占用的空间只有 int 类型的四分之一;short
short 数据类型是 16 位、有符号的以二进制补码表示的整数
最小值是 -32768(-2^15);
最大值是 32767(2^15 - 1);
Short 数据类型也可以像 byte 那样节省空间。一个 short 变量是 int 型变量所占空间的二分之一;
默认值是 0;
int
int 数据类型是 32 位、有符号的以二进制补码表示的整数;
最小值是 -2,147,483,648(-2^31);
最大值是 2,147,483,647(2^31 - 1);
一般地整型变量默认为 int 类型;
默认值是 0 ;
long
long 数据类型是 64 位、有符号的以二进制补码表示的整数;
最小值是 -9,223,372,036,854,775,808(-2^63);
最大值是 9,223,372,036,854,775,807(2^63 -1);
这种类型主要使用在需要比较大整数的系统上;
默认值是 0L;
float
float 数据类型是单精度、32 位、符合 IEEE 754 标准的浮点数;
float 在储存大型浮点数组的时候可节省内存空间;
默认值是 0.0f;
浮点数不能用来表示精确的值,如货币;
double
double 数据类型是双精度、64 位、符合 IEEE 754 标准的浮点数;
浮点数的默认类型为 double 类型;
double 类型同样不能表示精确的值,如货币;
默认值是 0.0d;
Boolean
boolean 数据类型表示一位的信息;
只有两个取值:true 和 false;
这种类型只作为一种标志来记录 true/false 情况;
默认值是 false;
char
- char 类型是一个单一的 16 位 Unicode 字符;
- 最小值是 \u0000(十进制等效值为 0);
- 最大值是 \uffff(即为 65535);
- char 数据类型可以储存任何字符;
# Java 常量
常量在程序运行时,不会被修改的量。
在 Java 中使用 final 关键字来修饰常量,声明方式和变量类似
final String str = "愧诗"; |
# 变量类型
Java 语言支持的变量类型有:局部变量、实例(成员)变量、类变量(静态变量)。
- 类变量(静态变量):独立于方法之外的变量,用 static 修饰。
- 实例(成员)变量:独立于方法之外的变量,不过没有 static 修饰。
- 局部变量:类的方法中的变量。
# 局部变量
- 局部变量声明在方法、构造方法或者语句块中;
- 局部变量在方法、构造方法、或者语句块被执行的时候创建,当它们执行完成后,变量就会被销毁;
- 访问修饰符不能用于局部变量;(在方法、构造方法、或者语句块中的变量不能被
public、private、protected
修饰) - 局部变量只在声明它的方法、构造方法或者语句块中可见;
- 局部变量是在栈上分配的。
- 局部变量没有默认值,所以局部变量被声明后,必须经过初始化,才可以使用。
# 实例(成员)变量
实例变量声明在一个类中,但在方法、构造方法和语句块之外;
成员变量 class A{
// 成员变量,可以先不初始化
String str;
public void sayHi(){}
}
当一个对象被实例化之后,每个实例变量的值就跟着确定;
实例变量在对象创建的时候创建,在对象被销毁的时候销毁;
实例变量的值应该至少被一个方法、构造方法或者语句块引用,使得外部能够通过这些方式获取实例变量信息;
实例变量可以声明在使用前或者使用后;
访问修饰符可以修饰实例变量;
实例变量对于类中的方法、构造方法或者语句块是可见的。一般情况下应该把实例变量设为私有。通过使用访问修饰符可以使实例变量对子类可见;
实例变量具有默认值。数值型变量的默认值是 0,布尔型变量的默认值是 false,引用类型变量的默认值是 null。变量的值可以在声明时指定,也可以在构造方法中指定;
实例变量可以直接通过变量名访问。但在静态方法以及其他类中,就应该使用完全限定名:ObejectReference.VariableName。
# 类变量(静态变量)
类变量也称为静态变量,在类中以 static 关键字声明,但必须在方法之外。
无论一个类创建了多少个对象,类只拥有类变量的一份拷贝。
静态变量除了被声明为常量外很少使用,静态变量是指声明为 public/private,final 和 static 类型的变量。静态变量初始化后不可改变。
静态变量储存在静态存储区。经常被声明为常量,很少单独使用 static 声明变量。
静态变量在第一次被访问时创建,在程序结束时销毁。
与实例变量具有相似的可见性。但为了对类的使用者可见,大多数静态变量声明为 public 类型。
默认值和实例变量相似。数值型变量默认值是 0,布尔型默认值是 false,引用类型默认值是 null。变量的值可以在声明的时候指定,也可以在构造方法中指定。此外,静态变量还可以在静态语句块中初始化。
静态变量可以通过:ClassName.VariableName 的方式访问。
类变量被声明为 public static final 类型时,类变量名称一般建议使用大写字母。如果静态变量不是 public 和 final 类型,其命名方式与实例变量以及局部变量的命名方式一致。
# 修饰符
Java 语言提供了很多修饰符,主要分为以下两类:访问修饰符、非访问修饰符;
修饰符用来定义类、方法或者变量,通常放在语句的最前端
# 访问修饰符
Java 支持 4 种不同的访问权限。
- default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
- private : 私有的,在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
- public : 公有的,对所有类可见。使用对象:类、接口、变量、方法
- protected : 受保护的,对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
修饰符 | 当前类 | 同一包内 | 子孙类(同包) | 子孙类 (不同包) | 其他包 |
---|---|---|---|---|---|
public | √ | √ | √ | √ | √ |
protected | √ | √ | √ | √/× 详情 | √ |
default | √ | √ | √ | × | × |
private | √ | × | × | × | × |
# 非访问控制修饰符
为了实现一些其他的功能,Java 也提供了许多非访问修饰符。
static 修饰符,用来修饰类方法和类变量。
final 修饰符,用来修饰类、方法和变量,final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。
abstract 修饰符,用来创建抽象类和抽象方法。
synchronized 和 volatile 修饰符,主要用于线程的编程。
详情
- static 修饰符
静态变量:
static 关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。 静态变量也被成为类变量。局部变量不能被声明为 static 变量。静态方法:
static 关键字用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。静态方法从参数列表得到数据,然后计算这些数据。对类变量和方法的访问可以直接使用 classname.variablename 和 classname.methodname 的方式访问。
- final 修饰符
final 变量
final 变量能被显式地初始化并且只能初始化一次。被声明为 final 的对象的引用不能指向不同的对象。但是 final 对象里的数据可以被改变。也就是说 final 对象的引用不能改变,但是里面的值可以改变。
final 修饰符通常和 static 修饰符一起使用来创建类常量。final 方法
类中的 final 方法可以被子类继承,但是不能被子类修改。
声明 final 方法的主要目的是防止该方法的内容被修改。
如下所示,使用 final 修饰符声明方法。final 类
final 类不能被继承,没有类能够继承 final 类的任何特性。
- abstract 修饰符
抽象类
抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充。
一个类不能同时被 abstract 和 final 修饰。如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则将出现编译错误。
抽象类可以包含抽象方法和非抽象方法。抽象方法
抽象方法是一种没有任何实现的方法,该方法的的具体实现由子类提供。
抽象方法不能被声明成 final 和 static。
任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类。
如果一个类包含若干个抽象方法,那么该类必须声明为抽象类。抽象类可以不包含抽象方法。
- synchronized 修饰符
synchronized 关键字声明的方法同一时间只能被一个线程访问。synchronized 修饰符可以应用于四个访问修饰符。
- volatile 修饰符
volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
一个 volatile 对象引用可能是 null。
# 循环
Java 中有三种主要的循环结构:
while 循环、do…while 循环、for 循环
while( 布尔表达式 ) { | |
// 循环内容 | |
} | |
---------------------------------------- | |
do { | |
// 代码语句 | |
}while(布尔表达式); | |
---------------------------------------- | |
for(初始化; 布尔表达式; 更新) { | |
// 代码语句 | |
} | |
---------------------------------------- | |
for(声明语句 : 表达式){ | |
// 代码句子 | |
} | |
---------------------------------------- |
break 关键字
break 主要用在循环语句或者 switch 语句中,用来跳出整个语句块。
break 跳出最里层的循环,并且继续执行该循环下面的语句。
continue 关键字
continue 适用于任何循环控制结构中。作用是让程序立刻跳转到下一次循环的迭代。
在 for 循环中,continue 语句使程序立即跳转到更新语句。
在 while 或者 do…while 循环中,程序立即跳转到布尔表达式的判断语句。
# 条件语句
if(布尔表达式){ | |
// 如果布尔表达式为 true 将执行的语句 | |
} | |
------------------------------------------- | |
if(布尔表达式){ | |
// 如果布尔表达式为 true 将执行的语句 | |
}else{ | |
// 如果布尔表达式为 flase 将执行的语句 | |
} | |
------------------------------------------- | |
if(布尔表达式 1){ | |
// 如果布尔表达式 1 的值为 true 执行代码 | |
}else if(布尔表达式 2){ | |
// 如果布尔表达式 2 的值为 true 执行代码 | |
}else if(布尔表达式 3){ | |
// 如果布尔表达式 3 的值为 true 执行代码 | |
}else { | |
// 如果以上布尔表达式都不为 true 执行代码 | |
} | |
------------------------------------------- | |
if(布尔表达式 1){ | |
//// 如果布尔表达式 1 的值为 true 执行代码 | |
if(布尔表达式 2){ | |
//// 如果布尔表达式 2 的值为 true 执行代码 | |
} | |
} |
# 匿名对象
匿名对象是指在创建对象时,只有创建对象的语句,却没有把对象地址赋值给某个变量,如:对于已存在的 Person 类
创建一个普通对象
Person P = new Person();
创建一个匿名对象
new Person();
# 特点
可直接使用
new Person ().getName (); //getName () 是这个类里面的一个方法
匿名对象在没有指定其引用变量时,只能使用一次
new Person ().getName ();; // 创建一个匿名对象,调用 getName () 方法
new Person ().getName ();; // 想再次调用 getName () 方法,要重新创建一个匿名对象
可作为方法参数 / 返回值
A a= new A (new Person); // 作为参数
return new Person (); // 作为返回值