一、类和对象
类是具有相同属性和方法的一组对象集合。
对象是事物的属性。
二、类
1. 定义
public class 类名{
}
2. 成员变量
在类中方法外定义的变量。
public class M1{
修饰符 数据类型 变量名 = 值;
public int i = 1;
}
3. 成员方法
在类中方法外定义的变量。
public class M1{
修饰符 返回值类型 方法名([参数列表]){
...
}
public void text(int i){
return i;
}
}
4. 局部变量
在方法中定义的对象,它的作用域只在这个方法中有效。
public class M1{
public void text(int i){
int j = i;
return j;//i和j都是局部变量
}
}
5. 主方法
类通过主方法来执行程序。
public static void main(String[] args) {
...
}
6. 构造器
构造器为对象初始化信息,构造器是特殊的方法。
(1). 定义
public class M1{
修饰符 类名([参数列表]){
...
}
public M1(){
System .out.println("默认构造器");
}
}
(2). 注意事项
- 构造器是特殊的方法,所以构造器可以重载使用。
public class M1{
public M1(){
System .out.println("默认构造器");
}
public M1(int i){
System .out.println("1参构造器");//重载
}
}
- 如果一个类中没有自定义构造器,那么编译器会默认提供一个空构造。
public class M1{
} 该类中没有定义构造器
编译:
public class M1{
public M1(){
} //编译器自动添加空构造
}
- 如果一个类中有自定义构造器,那么编译器不会提供构造器。
public class M1{
public M1(int i){
System .out.println("1参构造器");
}
} 该类中有自定义构造器
编译:
public class M1{
public M1(int i){
System .out.println("1参构造器");
} //编译器不会提供如何构造器,包括空构造。
}
- 构造器由new来调用。
public static void main(String[] args) {
M1 m = new M1();//new调用构造快M1()为m赋值。
}
- 构造器如果被private修饰,那么只能在当前类中创建对象。
7.块{ }
(1). 在方法中使用
代表局部代码块,在调用方法时执行。
public class M1{
public static void main(String[] args) {
j();
}
public void j(){
return 10;
}
}
主方法调用方法 j(),执行方法 j() 后面的局部代码块{return 10;}
(2). 在类中方法外使用
代表构造块,在创建对象时调用。
public class M1{
{
System.out.println("构造块1");
}
{
System.out.println("构造块2");
}
public static void main(String[] args) {
M1 m = new M1();
System.out.println("主方法");
}
}
输出:
构造块1
构造块2
主方法
在主方法中创建类M1的对象 m ,调用构造块。
(3)注意事项
- 若有多个构造块,则从上到下依次执行。
- 构造块先于构造器的代码执行。
- 在编译器编译时默认把构造块编译到要执行的构造器的上方。
public class M1{
//静态成员变量i
static int i = 10;
//构造块
{
i++;
}
//构造器
public M1(){//
M1(i);
System.out.println(i);
}
public M1(int j){
System.out.println(j);
}
//主方法
public static void main(String[] args) {
M1 m = new M1();
}
在主方法中创建M1类的对象m,需要调用构造块M1(),
但是构造块M1调用了M1(i),所以要执行的构造器是M1(i)。
所以public M1(int j){
i++;
System.out.println(j);
}
此时i=11,j=10。
}
8. 关键字this
this代表当前对象本身,存储当前对象的地址。
(1). 在构造器中使用,调用本类中的其他构造器。
public class M1{
public M1(){
this(1);//有一个参数,调用构造块2
}
public M1(int i){
System.out.println("构造块2");
}
}
注:构造器之间的相互调用不能出现循环。
(2). 在方法中使用,代表当前调用成员方法的对象。
public class M1{
int i=10;
public int j(int i) {
i=40;
System.out.println(this.i);
}
public static void main(String[] args) {
M1 m = new M1();
m.j(m.i);
}
}
在上述例子中this代表调用 j 方法的对象m,i=10。
如果把this去除,则i=40。
(3). 同名问题
1.如果一个方法中的局部变量和成员变量同名,那么就会产生就近原则,使用局部变量的赋值,使用this可以使该变量使用成员变量的值。
2.如果不存在同名问题,那么在使用成员变量时可将this省略。
(4). this不能出现在static修饰的方法中。
9. 关键字static(静态)
(1). 定义
public class M1{
1.定义静态变量
static 数据类型 变量名 = 值;
static int i = 10;
2.定义静态方法
修饰符 static 返回值类型 方法名([参数列表]){
...
}
public static int j (int i) {
return i;
}
3.定义静态块
static{
...
}
}
(2). 使用
public class M1{
static int i = 10;
public static int j() {
int k=20;
return k;
}
public static void main(String[] args) {
M1 m = new M1();
类名.静态变量名;
M1.i;
类名.静态方法名([参数列表]);
M1.j();
对象.静态变量名;
m.i;
对象.静态方法名([参数列表]);
m.j();
用类名的方法只能使用一次。
}
}
(3). 注意事项
- 静态的内容存储在静态区中,这个类的所有对象共享该类的静态内容。
- 在类的静态内容中可以直接使用静态内容,但不能使用成员内容,需要通过对象去使用。
- 在类的成员内容中可以直接使用静态内容,也可以直接使用成员内容。
- 静态块在类第一次加载后执行一次,且只执行一次。
9.执行顺序
静态块(仅执行一次) --> 主方法
创建对象 --> 构造块 --> 构造器
二、对象
1.创建对象
类名 对象名 = new 构造器;
2.使用
通过对象可以方位该类中的成员变量和成员方法。
对象名.成员变量;
对象名.成员方法([参数列表]);
3.范例
public class M1{
int i;
public int j(int i) {
i=40;
System.out.println(this.i);
}
public static void main(String[] args) {
M1 m = new M1();
m.i = 30;
m.j(m.i);
System.out.println(m.i);
}
}
- 该类中定义了一个
成员变量 i
和一个成员方法 j(int i)
,且无静态块、构造块、构造器。 - main方法进入栈中,主方法是一个静态方法,无法直接使用
成员变量 i
,所以需要创建一个对象m
,即M1 m = new M1();
。 - 当
new
执行的时候,会在堆内存中为对象m
开辟一个空间,成员变量i
跟随对象m
进入堆中,并赋默认值0
。 - 随后
new
调用构造器M1()
(由于改类中没有自定义构造器,编译器会自动创建一个空构造器),为成员变量i
赋值(由于是空构造器,所以未赋值,i 的值为默认值0)。 - 随后
new
将地址返回给引用,即m
代表的是对象在堆中的地址。 m.i = 30;
可以理解为:根据对象m
的地址,找到对象m
在堆中的变量i
,并赋值30。m.j(i);
可以理解为:根据对象m
调用方法j(int i)
,方法j(int i)
进栈执行,- 执行
j(int i)
中的代码,因为此时的局部变量i
和成员变量i
同名,所以此处的this
指代调用成员方法j(int i)
的对象m
。所以此处会输出30。 成员方法j(int i)
执行完毕,弹栈离开,主方法继续执行,输出成员变量i
的值:30。- 主方法执行完毕,弹栈离开。