构造方法,this关键字,static关键字,封装
1.构造方法
定义:构造方法是指实例化对象的方法
语法:[修饰符] 类名(参数){ }
根据有无参数分为有参构造和无参构造
1)有参构造
语法:[修饰符] 类名(type 实例变量,int age,String name......){ }
2)无参构造
语法:[修饰符] 类名(){ }
无参构造没有定义时,jvm会自动分配一个无参构造。
注:在使用有参构造时,jvm不会再默认分配一个无参构造,这时我们要自己定义一个无参构造。(反射只能识别无参构造)
1 public Dog(){ 2 health = 100; 3 love = 0; 4 } 5 public Dog(String _name,int _health,int _love,String _strain){ 6 name = _name; 7 health = _health; 8 love = _love; 9 strain = _strain; 10 }
3)局部变量和成员变量同名时的优先级
局部变量大于成员变量,所以改变局部变量的变量名称改为_name 或者 将成员变量改为 this.name(推荐后一种方法)
4)有参构造和无参构造是方法重载
2.this关键字
方法调用内存图:
方法调用内存图
this表示对象本身,有一个引用功能,指引用本身对象
this可以调用
1)this 实例变量
this . 变量名 = 成员变量 (可以解决局部变量和成员变量同名)
1 public Dog2(String name,int health,int love,String strain){ 2 System.out.println("this:"+this); 3 this.name = name; 4 this.health = health; 5 this.love = love; 6 this.strain = strain; 7 }
2)this 实例方法
this . 方法名
1 public Dog(String name,int health,int love,String strain){ 2 this.setName(name); 3 this.setHealth(health); 4 this.setLove(love); 5 this.setStrain(strain); 6 7 // showInfo(); 8 this.showInfo(); 9 }
3)this 构造方法
this(有参构造的参数) 或 this()
1 this(arg1,arg2,…) 2 3 4 public Dog(){ 5 6 } 7 8 public Dog(String name,int health,int love){ 9 this.setName(name); 10 this.setHealth(health); 11 this.setLove(love); 12 } 13 14 public Dog(String name,int health,int love,String strain){ 15 //this.setName(name); 16 //this.setHealth(health); 17 //this.setLove(love); 18 19 // this调用本类的其他构造方法 20 // System.out.println("test"); 21 this(name,health,love); 22 this.setStrain(strain); 23 24 // showInfo(); 25 //this.showInfo(); 26 }
注调用其他构造方法时,必须将其写在第一句,如
1 public Dog(String name,int health,int love,String strain){ 2 3 // this调用本类的其他构造方法 4 this(name,health,love); 5 this.setStrain(strain);
3.静态关键字(static)
需求:统计汽车工厂生成了多少量车?
- 统计工厂生成了多少量汽车的功能应该放到类功能上,不应该属于某个对象。
-声明一个变量用于统计个数,这个变量应该被类的实例共享。
-被类的实例共享的区域在方法区(Car.class)
-用static关键字声明这样的变量
static关键字表示静态,可以修改变量,也可以修饰方法。
1)静态变量(类变量)
语法:static 变量名 [ =初始化] static int count = 0;
被static修饰的变量成为静态变量,归类所有,也称为类变量(count),存储与方法区中的静态区,可以被类的实例共享访问。
访问方式
-类名.静态变量(推荐) Car.count;
-对象名.静态变量
2)静态方法(类方法)
语法:public static 返回值类型 方法名(){
return 返回值 ;
}
public static int getCarCount(){
return Car.count;
}
访问方式
-类名.静态方法名 (推荐)
-对象。静态方法名
3)访问权限(类中包含静态成员[ 静态变量和静态方法 ] 和实例成员[ 实例变量和实例方法 ])
静态方法不能访问非静态类成员;实例方法可以访问静态成员(为何如此?)
类加载机制
Car car = new Car(…);
当实例化一个对象时,jvm首先把Car.class加载到方法区
[1]读取Car.class 根据声明的成员变量计算申请内存需要的字节数
[2]读取Car.class 中的静态成员,给静态变量分配空间并初始化。
new Car 申请内存得到一个car对象,此时才有对象的空间。showInfo才可以通过car对象调用。
4.封装
定义:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。
步骤
-1.将变量私有化
-2.提供公共的设置器和访问器
-3.在设置器和访问器中添加业务校验逻辑
public class Dog{ // 【1】private 私有的,对外不可见 private String name; private int health; private int love; private String strain; // 【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 void setHealth(int health){ if(health < 0){ System.out.println("健康值不合法."); this.health = 0; }else{ this.health = health; } } public int getHealth(){ return this.health; } public void setLove(int love){ if(love < 0){ System.out.println("亲密度不合法."); this.love = 0; }else{ this.love = love; } } public int getLove(){ return this.love; } public void setStrain(String strain){ if(strain.equals("")){ System.out.println("品种不能为空."); }else{ this.strain = strain; } } public String getStrain(){ return this.strain; } public Dog(){ } public Dog(String name,int health,int love,String strain){ this.setName(name); this.setHealth(health); this.setLove(love); this.setStrain(strain); } public void showInfo(){ System.out.print("我的名字叫"+this.name); System.out.print(",健康值"+this.health); System.out.print(",亲密度"+this.love); System.out.println(",我是一只"+this.strain); } }
5.静态常量
定义:在程序运行中,如果有一个变量不会发生改变,可以声明一个静态常量,用static final 修饰。
public class Penguin{ private String name; private int health; private int love; private String gender; // gender为Q仔 将Q仔改为雄 static final String SEX_MALE = "雄"; static final String SEX_FEMALE = "雌"; public class Test02{ public static void main(String[] args){ Penguin penguin = new Penguin("大脚",100,0,Penguin.SEX_MALE);
//用 Penguin.SEX_MALE 而不用Q仔,好处是更新程序时便于更改 } }
6.代码块
1)普通代码块
普通代码块一般存在于方法或者类、方法等的定义中,普通代码块形成一个作用域。
1 public class Test03{ 2 3 public static void main(String[] args){ 4 5 int count_1 = 10; 6 7 // 普通代码块 8 { 9 int count_2 = 20; 10 //System.out.println("count_1:"+count_1); 11 //System.out.println("count_2:"+count_2); 12 } 13 14 // error 15 System.out.println("count_2:"+count_2); 16 17 } 18 }
2)构造代码块
构造代码块位于类中。构造代码块在构造方法前执行。构造一个对象执行一次。
1 public class Person{ 2 String name; 3 int age; 4 5 // 构造代码块 6 { 7 System.out.println("构造代码块"); 8 } 9 10 public Person(){ 11 System.out.println("构造方法"); 12 } 13 public Person(String name,int age){ 14 this.name = name; 15 this.age = age; 16 } 17 }
3)静态代码块
静态代码块位于类中,归类所有,用static修饰。在类加载时执行,在构建多个对象时只执行一次
1 public class Person{ 2 String name; 3 int age; 4 5 static{ 6 System.out.println("静态代码块"); 7 } 8 9 public Person(){ 10 System.out.println("构造方法"); 11 } 12 public Person(String name,int age){ 13 this.name = name; 14 this.age = age; 15 } 16 }
4)同步代码块(多线程讲解)
总结:静态代码块一般用于初始化静态资源,构造代码块一般用于初始化实例成员。