类的成员介绍
- 属性
- 方法
1. 属性
1.类中属性的作用:用来描述类所具有的某些特征
2.类中属性声明和使用:
访问权限修饰符 [final] [static] 属性名[ = 属性值];
2.1 访问权限修饰符有四种(范围从小到大):private 、 缺省、protected 、public;
private:类中的属性仅仅可以在类的内部调用
缺省: 类中属性可以在同一个包中被调用
protected:类中的属性仅仅可以同一个包中和其他包中继承了该类的子类中调用
public:可以在任何一个地方被调用
2.2 final、static关键家后续会有专门的章节来讲解。
属性(成员变量) vs 局部变量
不同点 | 相同点 | |
---|---|---|
属性(成员变量) |
1.直接定义在类的一对 {}内 2.可以在声明属性时,指明其权限,使用权限修饰符。 3.类的属性,根据其类型,都有默认初始化值。基本数据类型变量初始值按照基本数据类型的初始值规则赋值。引用数据类型变量初始值按照基本数据类型的初始值规则赋值。 4.属性:加载到堆空间中(非 static) |
1.定义变量的格式:数据类型 变量名 = 变量值 2.先声明,后使用 3.变量都有其对应的作用域 |
局部变量 | 1.声明在方法内、方法形参、构造器形参、构造器内部的变量。 2.不可以使用权限修饰符。 3.在调用局部变量之前,一定要显式赋值。否则会报错。 4.局部变量加载时存放在栈空间。 |
2.方法
类中方法的声明和使用:
1.类中方法的作用:描述该类所具有的功能。
2.方法的声明:
权限修饰符 [abstract] [final] [static] 返回值类型 方法名(形参列表) {
方法体;
}
注意:[abstract] [final] [static] 后面会一一讲解。
3. 说明:
3.1 权限修饰符(范围从小到大):private 、 缺省、protected 、public(与属性的访问权限相同);
3.2 返回值类型:void和基本数据类型和引用数据类型;
3.2.1 有返回值 VS 无返回值void
如果方法有返回值,则必须在方法声明时,指定返回值类型,同时,方法中需要使用“return 返回值” 来返回指定类型的数据。
如果没有返回值,则在方法声明时,使用void标识。通常,没有返回值的方法体中不需要使用return语句。但是,如果需要使用的话,只能“return ;”表示结束方法的执行。
3.2.2 介绍return关键字
3.2.2.1 return 关键字的使用:只能使用在方法体中;
3.2.2.2 作用:①结束方法的执行
②针对有返回值类型的方法,使用“return 数据”的方式返回所需要的数据。
3.2.2.3 注意点:return关键字之后不可以在声明其他语句;这一点和continue、break有相同的限制。
3.3 方法名:符合标识符的规则和规范即可。“见名知意”。
3.4 形参列表:基本数据类型和引用数据类型的声明,可以定义多个形参,多个形参之间用“,”分隔;
4. 方法重载:“两同一不同”
“两同”:在同一个类中,函数名相同
“一不同”:形参列表不同:(参数类型或者参数个数不同)
注意:方法重载仅仅参考这两个标准,不满足这两个标准的任何一个都不是重载。
5. 方法重写:
方法重写是指子类在继承父类的时候,对父类的方法进行重写。
方法重写有以下几个要求:
5.1 子类重写的方法必须和父类被重写的方法具有相同的方法名称,参数列表
5.2 子类重写的方法的返回值类型不能大于父类被重写的方法的返回值类型。
5.2.1 如果父类被重写的方法返回类型是void,子类的返回类型必须是void。
5.2.2 如果父类被重写的方法返回值类型是基本数据类型,则子类的方法的返回值类型必须是相同的基本数据类型。
5.2.3 如果父类被重写的方法返回值类型是A类型(Object),则子类重写的方法的返回值类型可以是A类型,也可以是A类的子类类型。
5.3 子类重写的方法抛出的异常不能大于父类被重写的方法抛出的异常。
5.4 子类重写的方法使用访问权限修饰符不能小于父类被重写的方法权限修饰符。
6.方法的使用:
6.1 方法中可以调用类中的属性和方法;
6.2 特殊地,如果方法A直接或间接的调用方法A自身,则这种方法成为递归方法。这种方法包括递归边界和递归体。
注意:
子类不能重写父类中声明为private权限的方法,即使在子类中写了和父类同名同参数列表的方法,这两个方法之间也没有重写的关系。
原因:子类中看不到父类中的private权限的方法(该访问权限修饰符修饰的方法仅类内可调用),所以两个方法之间就无所谓重写了。
注意:在类的方法中,可以调用其他方法,但是不能定义新的方法。(不可以在方法内定义方法)
2.1 方法的重载
1.定义:在同一个类中,允许存在一个以上的同名方法,只要他们的参数个数或者参数类型不同即可。
2.“两同一不同”
同一类中,相同的方法名
参数列表不同:参数个数不同或者参数列表不同(二者至少满足一个)
3.判断类中两个方法是否重载
首先,仅仅需要从“两同一不同”出发。
其次,方法的重载与方法的返回值类型、权限修饰符、形参变量名和方法体都无关。
4. 学习方法重载,更重要的是要理解,在程序执行过程中,程序调用的哪个方法:
通过 方法名 --> 形参列表 --> 确定调用的哪个方法
这三步接口确定程序执行调用的哪个方法。
2.2 可变个数的形参
1. 在JDK 1.5(也就是JDK 5.0)之前提供了Varargs(variable number of arguments)机制,允许直接定义能和多个实参相匹配的形参。从而,可以用一种更简单的方式来传参数。
2. 在JDK 1.5之前编程人员都是通过将形参定义成数组的方式来接受多个同类型的参数。
3. 在JDK 1.8(也就是JDK 8.0)之后,新增了一种可变个数形参的方法。
4. 下面详细说一下JDK 1.8之后如何定义可变个数的形参
4.1 定义可变个数形参的具体格式:
数据类型... 变量名
4.2 传入的采纳数个数可以0个或者多个。
4.3 可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载。
4.4 可变个数形参的方法与本类中方法名相同、形参类型也相同的数组之间不构成重载。即二者不可共存。
4.5 可变个数参数的方法中,必须声明在所有同名方法之后。
4.6 可变个数形参的方法,在同一个类中只能声明一个。
2.3 方法参数的值传递机制(☆☆☆)
如果形参列表中的变量类型是基本数据类型,则此时形参保存的是变量的数据值。形参的变化不会影响实参的值。
如果形参列表中变量类型是引用数据类型,则此时形参保留的是数据的地址值。对形参所指向地址的数据的修改,也会反映给实参。
3. 构造函数(构造器)
类的结构之三:构造器(构造方法、constructor)
1. 构造器的使用
1.1 创建对象
1.2 初始化对象的属性
2. 说明
2.1 在类中,如果没有显式的定义构造器的话,系统将会默认提供了无参构造器。但是,一旦显式的定义无参或者有参构造器之后,系统将不再提供默认的无参构造器。
2.2 构造器的定义方式:
权限修饰符 类名(形参列表) {
构造函数体;
}
注意: 构造器没有返回值。
2.3 一个类中可以定义多个构造器,多个构造器之间构成重载。
2.4 一个类中至少有一个构造器(显式或者隐式的提供);
2.5 通常类中定义的构造器都会声明为public的访问权限。但是,也不排除使用private的访问权限,例如:单例模式。
3. 类中属性的赋值的优先级
① 默认初始化
② 显式初始化、非static代码块(这两者之间按照声明顺序赋值)
③ 构造器赋值
④ 通过"对象.属性" 或者 "对象.方法"的方法赋值。
注意:对象的属性值一般是通过优先级较低的方式赋予的值
4.代码块
1. 代码块的作用:用来初始化类或者对象的属性;
2. 代码块的使用:
[static] { 逻辑代码; }
3. 静态代码块和非静态代码块的区别
3.1 静态代码块
3.1.1 随着类的加载而执行,仅仅执行一次;
3.1.2 作用:可以用来初始化类的信息;
3.1.3 如果类中定义了多个静态代码块,程序按照声明的顺序执行;
3.1.4 静态代码块的执行,会优先于非静态代码块执行。因为类的加载会优于对象的声明;
3.1.5 静态代码块中只能调用静态属性和方法,不能调用非静态的属性和方法;
3.2 非静态代码块
3.2.1 随着对象的创建而执行,创建一个对象,非静态代码块执行一次;
3.2.2 作用:可以用来初始化对象的信息;
3.2.3 如果类中定义了多个非静态代码块,程序按照声明的顺序执行;
3.2.4 非静态代码块中既可以调用非静态的属性和方法,也可以调用静态属性和方法;因为静态属性和方法加载到内存中的时机会早于对象的创建,所以非静态代码块中可以调用静态属性和方法。
4. 对属性赋值的优先级(从高到低):
默认初始化;
显式初始化、非静态代码块;(按照声明顺序执行)
构造函数;
"对象.属性"或者"对象.方法"赋值;
5. 内部类
6.所有类的根父类Object类
- Object类是所有Java类的根父类;
- 如果在类的声明中未使用extends关键字指明其父类,则默认父类为java.lang.Object类
- Object类中的功能(属性、方法)就具有通用性。
属性:无
方法:equals()、 toString() 、 getClass() 、hashCode() 、clone() 、finalize()、 wait() 、notify()、notifyAll() - Object类只声明了一个空参的构造器。
6.1 equals()
-
是一个方法,而非运算符。
-
只能适用于引用数据类型。
-
Object类中equals()的定义:
public boolean equals(Object obj){ return (this == obj); } 说明: Object类中定义的equals()和==的作用是相同的, 比较两个对象的地址值是否相同, 即两个引用是否指向同一个对象实体。
-
像String、Date、File、包装类等都重写了Object类中的equals()方法.
-
通常情况下,我们自定义的类如果使用equals()的话,也通常是比较两个对象的"实体内容"是否相同。那么,我们就需要对Object类中的equals()进行重写。
重写的原则:比较两个对象的实体内容是否相同。
回顾==的使用
- == 是运算符。
- 可以使用在基本数据类型变量和引用数据类型变量中。如果比较的是基本数据类型变量:比较两个变量保存的数据是否相等。(不一定类型要相同) 如果比较的是引用数据类型变量:比较两个对象的地址值是否相同,即两个引用是否指向同一个对象实体
- 补充: == 符号使用时,必须保证符号左右两边的变量类型一致。
6.1.1 重写equals()方法的原则
- 对称性:如果x.equals(y)返回是“true”,那么y.equals(x)也应该返回是“true”。
- 自反性:x.equals(x)必须返回是“true”。
- 传递性:如果x.equals(y)返回是“true”,而且y.equals(z)返回是“true”,那么z.equals(x)也应该返回是“true”。
- 一致性:如果x.equals(y)返回是“true”,只要x和y内容一直不变,不管你重复x.equals(y)多少次,返回都是“true”。
- 任何情况下,x.equals(null),永远返回是“false”;x.equals(和x不同类型的对象)永远返回是“false”
6.2 toString的使用
- 当我们输出一个引用对象时,实际上就是调用当前对象的toString()。
- Object类中toString的定义方法
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
- 像String、Date、File、包装类等都重写了Object类中的toString()方法。使得在调用toString()时,返回"实体内容"信息.
- 自定义类如果重写toString()方法,当调用此方法时,返回对象的"实体内容".
Customer类的toString()方法
public String toString() {
return "Customer [name=" + name + ", age=" + age + "]";
}