1.构造方法
1.1 构造方法与成员方法的区别
构造方法分为无参构造和有参构造,其中有参构造方法和无参构造方法为方法的重载关系。
构造方法在初始化一个类的对象时进行调用,它没有返回值,方法名与类名相同,而成员方法是则是由对象主动调用,它有返回值,表现为对象的操作行为。
简单来说,构造方法定义了一个对象,赋予了对象属性值,而成员方法由对象主动调用,是对象具体行为的表现。
1.2 无参构造
[修饰符] 类名(){
}
public Dog(){ }
当类中没有定义无参构造时,jvm会默认分配一个无参构造。
1.3 有参构造
[修饰符] 类名(Type arg1,Type arg2,…){
// 初始化代码
}
public Dog(String name,int health,int love,String strain){ name = name; health = health; love = love; strain = strain; }
在实例化有参构造方法的时候必须按照有参构造的参数列表的内容传值。
当在类中定义了有参构造方法后,jvm不会再默认分配无参构造,因此在定义了有参构造方法后,应再定义一个无参构造方法,以便对对象进行创建。
1.4 对象初始化的内存图
当一个类在进行编译时,jvm会将该类的字节码文件加载到方法区,并读取类中定义的成员变量和方法,完成方法的加载并根据定义的属性计算出需要申请的内存。在使用new关键字创建一个对象时,jvm会在堆区申请内存并进行初始化,该对象的内存地址储存在栈区中,当我们调用构造方法对该对象的属性进行赋值时,会通过栈区的内存地址来对堆区的对象进行访问。
2.封装
封装:将类的某些信息私有化,不允许外部程序直接访问,而是通过该类提供的设置器和访问器来实现对私有化信息的操作和访问。
封装的步骤
[1]属性私有化
[2]提供公共的设置器和访问器
[3]在设置器和访问器中添加业务校验逻辑
public class Dog{ // 【1】private 私有的,对外不可见 private String name; // 【2】提供公共的设置器(setter)和访问器(getter) public void setName(String name){ // 【3】逻辑校验 if(name.equals("")){ System.out.println("姓名不能为空."); }else{ this.name = name; } } public String getName(){ return this.name; } public Dog(){ } public Dog(String name){ this.setName(name); } public void showInfo(){ System.out.print("我的名字叫"+this.name); } }
3. This关键字
this表示对象本身(引用),一般而言,类的外部使用对象名本身,类的内部使用This关键字。
3.1 This调用本类中的属性
public class Dog{
String name;
int health;
int love;
String strain;
public Dog2(String name,int health,int love,String strain){
this.name = name;
this.health = health;
this.love = love;
this.strain = strain; //调用本类中的属性
}
}
this用于访问本类属性,解决了局部变量和成员变量同名的问题。
3.2 This调用本类的方法
public class Dog{
private String name; public void setName(String name){ if(name.equals("")){ System.out.println("姓名不能为空."); }else{ this.name = name; } } public String getName(){ return this.name; } public Dog(){ } public Dog(String name){ this.setName(name); //调用本类中的方法 } public void showInfo(){ System.out.print("我的名字叫"+this.name); } }
3.3 This调用本类的其他构造方法(调用时应放首行)
public class Dog{ private String name;
private String heath; public void setName(String name){ if(name.equals("")){ System.out.println("姓名不能为空."); }else{ this.name = name; } } public String getName(){ return this.name; }
public void setHeath(String heath){ if(heath<0){ System.out.println("健康值不能为0");
this.heath=0; }else{ this.heath=heath; } } public String getHeath(){ return this.heath; }
public Dog(){
} public Dog(String name){ this.setName(name); }
public Dog(String name){
this(name,health,love); //调用本类其他构造方法
this.setStrain(strain);
}
}
4. static 关键字
static 关键字表示静态,可以修改变量,也可以修饰方法。
4.1 静态变量
静态变量由static修饰,存放在方法区,可被类中的对象共享访问。
访问方式有两种:[1] 类名.静态变量(推荐); [2] 对象.静态变量。
public class Car{ String brand; String type; float price; static int count = 0; //定义一个静态变量 public Car(){ Car.count++; } public Car(String brand,String type,float price){ this.brand = brand; this.type = type; this.price = price; Car.count++; } public void showInfo(){ System.out.println("车辆信息:"); System.out.println("品牌:"+this.brand); System.out.println("型号:"+this.type); System.out.println("价格:"+this.price); System.out.println("我是第"+Car.count+"辆车"); //对静态变量进行访问 } }
4.2 静态方法
静态方法由static 修饰,归类所有。
[修饰符] static 返回值类型 方法名(arg…){ }
访问方式有两种:[1] 类名.方法名(推荐); [2] 对象.方法名。
需注意的是,实例方法可以访问静态成员,而静态方法不能访问非静态成员。(在静态成员被定义时,对象还未被定义。)
图示小结:
5. 代码块
代码块由{ }进行声明,根据其位置可以分为普通代码块、静态代码块、构造代码块、同步代码块(我还没学到)。
5.1 普通代码块
普通代码块一般存在于方法或者类、方法等的定义中,普通代码块形成一个作用域。
public class Test03{ public static void main(String[] args){ int count_1 = 10; // 普通代码块 { int count_2 = 20; System.out.println("count_1:"+count_1); System.out.println("count_2:"+count_2); } // 在代码块的作用域外无效 System.out.println("count_2:"+count_2); } }
5.2 构造代码块
构造代码块位于类中。构造代码块在构造方法前执行。构造一个对象执行一次。
public class Person{
String name;
int age;
// 构造代码块
{
System.out.println("构造代码块");
}
public Person(){
System.out.println("构造方法");
}
public Person(String name,int age){
this.name = name;
this.age = age;
}
} //每当构造一个对象时,都会执行一次构造代码块中的语句。
5.3 静态代码块
静态代码块位于类中,归类所有,用static修饰。在类加载时执行,在构建多个对象时只执行一次。
public class Person{ String name; int age; static{ System.out.println("静态代码块"); } //静态代码块 public Person(){ System.out.println("构造方法"); } public Person(String name,int age){ this.name = name; this.age = age; } } //静态代码块在加载类时执行,在构建多个对象时只执行一次
小结:
静态代码块一般用于初始化静态资源,构造代码块一般用于初始化实例成员。