整理了长风老师在Day0506的面向对象章节的随堂代码
package com.xy.java.day06.oop_block_by_xy.block12.building2;
/**
* @program: day06_javase_oop2_block
* @description: 顺序:1.静态成员,2.成员变量+代码块(构造代码块),3.构造方法(构造器)
* @author: xj992adolphxy@163.com
* @create: 2021-04-04 10:38
**/
/**
* 注意加断点的位置。
* 类中成员变量赋值语句本行加断点,显示是一个眼睛
* 赋值语句本行、方法中第一行加断点,显示是红点
*
* 记忆点1:加载类-创建对象
* 加载类:首次声明类以后,需要加载类到方法区。
* 从头部执行静态成员或静态代码块赋值语句。执行结束后,类加载完成。
* 然后,如果有创建对象,则根据声明类语句创建对象的后半句,根据调用的对应参数构造方法,在类中找对应的构造方法
* 找到构造方法,执行方法中的语句,跳回到创建对象语句。
* 创建对象完成
* 注意:同一个类创建第1个对象就直接从方法区找类。之前是加载类
* 以后的代码应该大多都是创建对象,很少有再次声明类。
* 因为加载类结束了,静态成员变量赋值语句不再执行。
*
* 创建对象:根据创建对象调用的参数个数、类型,找到类中对应参数构造方法,暂时不执行
* 然后从类头,从上到下按照代码顺序,执行成员变量赋值语句、代码块
* 最后跳回刚才记住位置的构造方法,执行构造方法中的语句
* 回到创建对象语句,创建对象完成。
*
* 记忆点2:成员变量(初始化+赋值)
* 1.创建对象
* (首次声明类创建对象:加载类到方法区,执行初始化的静态成员,直接返回到声明类、创建对象语句。不执行成员变量赋值语句、代码块)
* (第二次声明类创建对象:调用方法区类,执行成员位置赋值语句,默认初值——>赋值)
* 2.成员变量赋值语句:类头往下位置,显式赋值
* 3.代码块:类头往下位置,大括号中,构造代码块赋值
* //小括号:() 中括号:[] 大括号:{}
* //这里说的是第3个:大括号{}
* 4.构造方法(构造器)中,空参数、单参数等等,传递参数赋值
* 创建完对象了用对象名加点、构造方法传参数赋值
*
* 记忆点3:规范的成员位置代码顺序:
* 1.成员变量
* 2.构造代码块(大括号{})
* 面试:构造代码块放在成员变量上面也能执行,编译器的作用
*
* 记忆点4:构造方法中,this调用其他构造方法
* 顺序:
* 1.跳到this调用的对应参数的构造方法
* 2.再跳到类头成员位置,按照创建对象的执行顺序,从上到下执行赋值
* 3.成员位置:成员变量+成员位置的代码块,遇到静态变量、静态代码块跳过(类加载已经赋值过)
* 4.成员位置结束,跳回到this调用的构造方法
* 5.执行this调用构造方法,空参数、单参数等等
* 6.跳回到最开始的构造方法中,this调用构造方法位置
* 7.这一句this调用构造方法结束
* 8.继续这个构造方法,执行this调用之后的代码
*
* 记忆点5:构造方法和构造代码块作用对比
* 1.构造方法(构造器):创建某一个对象最后一步时调用
* 2.构造代码块:位于成员位置,创建对象一开始
* 3.可以抽取1.代码到2.
*
* 记忆点6:代码规范
* 1.关于this:使用可以,但是意义不大
* 2.成员位置顺序:
* 成员变量定义语句——>构造代码块(大括号{})
*
* */
public class Demo {
public static void main(String[] args) {
Cat c = new Cat();//1.加载类Cat到方法区,跳到类头找静态变量,首次加载类要进行静态变量初始化
//3.加载类结束。开始创建对象。在语句中根据参数找到类中对应参数构造方法:空参数构造方法
//11.回到创建对象语句,成员位置赋值结束。开始接收构造方法的参数。
//13.从构造方法回来,创建对象结束。继续执行
System.out.println(c.age);//14.访问刚才创建对象的age属性
Cat c2 = new Cat(18);//15.创建第二个对象,还是经过类头,不执行给静态变量初始化和执行赋值语句。
//22.创建第二个对象结束。后续过程不再记录
System.out.println(c2.age);
//Cat c = new Cat(1, "旺财");
//Cat c2 = new Cat();
System.out.println(c.age + " " + c.name);
//Cat c = new Cat();
System.out.println(Cat.staticA);
}
}
class Cat {
int age = 10;//5.从构造方法过来,执行成员位置的语句:成员变量赋值、代码块(构造代码块)
//17.从上到下执行成员位置的语句:成员变量赋值语句、代码块
String name = "张三";
static int staticA = 10;//2.找到静态变量,先默认初始化int类型默认赋值0。然后执行赋值语句,赋值10
//跳回刚才首次加载类的语句:在main()方法第一行。
//16.经过静态成员位置的静态变量赋值语句,但是不再执行
{
age = 20;//6.从构造方法过来,执行成员位置的语句:成员变量赋值、代码块(构造代码块)
name = "李四";
System.out.println("我创建了一个Cat对象,这里是每次创建对象都会经过的{成员位置的构造代码块}");
//问题2.这里能使用this关键字
String name1 = this.name;
this.test();//7.从构造方法过来,执行成员位置的语句:成员变量赋值、代码块(构造代码块)
//这里调用类中的一个成员方法,跳转到这个方法
//9.执行完被调用的方法,还跳回来到这里继续执行代码块(构造代码块)
//问题1.这里能不能给静态成员赋值
Cat.staticA = 100;//10.给类的静态成员赋值,可以执行。但是不规范
//解答1.这里赋值不好,这种方式不规范
//显然需要一种类加载时执行的代码块:静态代码块
}
public Cat() {//4.找到空参数构造方法。先不执行构造方法。从类头,自上而下,按照代码顺序,执行成员变量赋值、代码块(构造代码块)
//12.因为main()中创建对象用的构造方法是空参数构造方法。这里没有赋值输出操作,回到创建对象语句,创建结束。
//age = 10;
}
public Cat(int age) {//20.成员变量语句执行结束。回到单参数构造方法
this.age = age; //21.age参数传入,给对象的age成员变量赋值。构造方法执行结束
//22.回到main()语句中创建对象语句
}
public Cat(int age, String name) {
this.age = age;
this.name = name;
}
public void test() {
System.out.println("test");//8.被成员位置的代码块中的语句调用。这里是类中的成员方法
//19.执行成员位置代码块的语句,调用test(),输出
}
}