封装
构造方法
构造方法是一种特殊的方法,用于构造实例化对象
形式:[修饰符] 类名称(){
}
构造方法又分为无参构造和有参构造方法。
无参构造方法
无参构造就是不向方法里传参数例如:public Dog(){ };
无参构造的作用:给属性赋值。
若没有定义无参构造则jvm默认分配一个。
1 public class Dog{ 2 3 String name; 4 int health; 5 int love; 6 String strain; 7 8 public Dog(){ 9 System.out.println("构造方法"); 10 health = 100; 11 love = 0; 12 } 13 … 14 }
有参构造方法
顾名思义有参构造就是向方法里传参数例如:
public Dog(type arg,type arg1...){ }
1 public class Dog{ 2 3 String name; 4 int health; 5 int love; 6 String strain; 7 8 public Dog(String _name,int _health,int _love,String _strain){ 9 name = _name; 10 health = _health; 11 love = _love; 12 strain = _strain; 13 }
有参构造常见的问题
总结:
定义了有参构造方法后,一定要习惯定义无参构造方法。
有参方法与无参方法是重载关系。
定义了有参构造,jvm不在默认分配一个无参构造。
1 public class Dog{ 2 3 String name; 4 int health; 5 int love; 6 String strain; 7 8 /* 9 public Dog(){ 10 System.out.println("构造方法"); 11 health = 100; 12 love = 0; 13 } 14 */ 15 16 public Dog(String _name,int _health,int _love,String _strain){ 17 name = _name; 18 health = _health; 19 love = _love; 20 strain = _strain; 21 } 22 23 public void showInfo(){ 24 System.out.print("我的名字叫"+name); 25 System.out.print(",健康值"+health); 26 System.out.print(",亲密度"+love); 27 System.out.println(",我是一只"+strain); 28 } 29 } 30 Dog dog = new Dog(); 31 dog.name = name; 32 dog.health = 100; 33 dog.love = 0; 34 dog.strain = strain;
This关键字
this关键字指的是对象的本身,用于访问本对象属性,用来区分成员变量和局部变量。
【1】this调用属性
1 public Car(String brand,String type,float price){ 2 this.brand = brand; 3 this.type = type; 4 this.price = price; 5 6 }
【2】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(arg1,arg2...)
1 public Dog(){ 2 3 } 4 5 public Dog(String name,int health,int love){ 6 this.setName(name); 7 this.setHealth(health); 8 this.setLove(love); 9 } 10 11 12 public Dog(String name,int health,int love,String strain){ 13 //this.setName(name); 14 //this.setHealth(health); 15 //this.setLove(love); 16 17 // this调用本类的其他构造方法 18 // System.out.println("test"); 19 this(name,health,love); 20 this.setStrain(strain); 21 22 // showInfo(); 23 //this.showInfo(); 24 }
对象初始化内存图
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 }
1 public class Test04{ 2 public static void main(String[] args){ 3 4 Dog2 dog = new Dog2("二狗",100,0,"土狗"); 5 System.out.println("dog:"+dog); 6 dog.showInfo(); 7 } 8 }
通过打印this中的引用,可以看出对象dog和this指向同一内存。
一般而言,dog用于类的外部,this用于类的内部。因为类的内部根本不知道dog变量名的存在。
方法调用内存图
static
静态变量
形式:
[修饰符] static 类型 变量名 = [默认值]
静态变量也称类变量,在该类下的方法都可以访问,也就是共享变量。
访问方式
类名.静态变量【效率高推荐】
对象.静态变量
1 public class Car{ 2 String brand; 3 String type; 4 float price; 5 6 static int count = 0; 7 8 public Car(){ 9 Car.count++; 10 } 11 12 public Car(String brand,String type,float price){ 13 this.brand = brand; 14 this.type = type; 15 this.price = price; 16 Car.count++; 17 } 18 19 public void showInfo(){ 20 System.out.println("车辆信息:"); 21 System.out.println("品牌:"+this.brand); 22 System.out.println("型号:"+this.type); 23 System.out.println("价格:"+this.price); 24 System.out.println("我是第"+Car.count+"辆车"); 25 } 26 27 28 }
1 public class Test01{ 2 public static void main(String[] args){ 3 Car car1 = new Car("奔驰","漏油GL300",66); 4 car1.showInfo(); 5 6 7 Car car2 = new Car("奔驰","漏油GL400",66); 8 car2.showInfo(); 9 10 System.out.println(Car.count); 11 System.out.println(car1.count); 12 System.out.println(car2.count); 13 14 } 15 }
静态常量
在程序运行过程中值不会发生改变的量叫常量。
1 public class Penguin{ 2 3 private String name; 4 private int health; 5 private int love; 6 private String gender; 7 8 static final String SEX_MALE = "雄"; 9 static final String SEX_FEMALE = "雌"; 10 11 public void setName(String name){ 12 this.name = name; 13 } 14 public String getName(){ 15 return this.name; 16 } 17 18 public void setHealth(int health){ 19 if(health>100 && health<1){ 20 this.health = 60; 21 System.out.println("健康值必须在1-100之间,默认为60"); 22 }else{ 23 this.health = health; 24 } 25 } 26 public int getHealth(){ 27 return this.health; 28 } 29 30 public void setLove(String love){ 31 this.love = love; 32 } 33 public int getLove(){ 34 return this.love; 35 } 36 37 public void setGender(String gender){ 38 this.gender = gender; 39 } 40 public String getGender(){ 41 return this.gender; 42 } 43 44 public Penguin(){ 45 46 } 47 public Penguin(String name,String gender){ 48 this.setName(name); 49 this.setGender(gender); 50 } 51 52 public Penguin(String name,int health,int love,String gender){ 53 this(name,gender); 54 this.setHealth(health); 55 this.setLove(love); 56 } 57 58 public void showInfo(){ 59 System.out.print("我的名字叫"+name); 60 System.out.print(",健康值"+health); 61 System.out.print(",亲密度"+love); 62 System.out.println(",性别"+gender); 63 } 64 65 66 } 67 public class Test02{ 68 public static void main(String[] args){ 69 70 Penguin penguin = new Penguin("大脚",100,0,Penguin.SEX_MALE); 71 } 72 }
形式:
staitc final type 名称 = [值]
静态方法
形式:
[修饰符] static 返回值类型 方法名称 { }
访问形式
类.静态方法(效率高推荐)
对象.静态方法
静态方法访问非静态成员
1 public class Car{ 2 String brand; 3 String type; 4 float price; 5 6 static int count = 0; 7 8 public Car(){ 9 Car.count++; 10 } 11 12 public Car(String brand,String type,float price){ 13 this.brand = brand; 14 this.type = type; 15 this.price = price; 16 Car.count++; 17 } 18 19 public void showInfo(){ 20 System.out.println("车辆信息:"); 21 System.out.println("品牌:"+this.brand); 22 System.out.println("型号:"+this.type); 23 System.out.println("价格:"+this.price); 24 System.out.println("我是第"+Car.count+"辆车"); 25 } 26 27 public static int getCarCount(){ 28 // 在静态方法中访问实例变量 29 // System.out.println("品牌:"+brand); 30 31 //showInfo(); 32 //this.showInfo(); 33 34 return Car.count; 35 } 36 }
总结:
静态方法不能访问非静态成员
实例方法能访问静态成员
类加载机制
Car car = new car();
1.实例化一个对象的时候jvm先把car.class 加载到方法区,
2.读取car.class计算声明成员变量所申请的的字节。
3.读取car.class中的静态变量,并给其分配空间并初始化
4.new car申请得到一个对象,然后给其分配空间;showInfo才可以通过car对象调用
之所以实例方法能访问静态成员,静态方法不能访问非静态成员,就是因为静态方法、成员先于实例方法、成员加载。
小结
封装
封装:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。
封装步骤
1.私有制变量
2.提供公共设置器(setArg)和访问器(getArg)
3.在设置器于访问器中设置业务逻辑校验。
1 public class Dog{ 2 3 // 【1】private 私有的,对外不可见 4 private String name; 5 private int health; 6 private int love; 7 private String strain; 8 9 // 【2】提供公共的设置器(setter)和访问器(getter) 10 public void setName(String name){ 11 // 【3】逻辑校验 12 if(name.equals("")){ 13 System.out.println("姓名不能为空."); 14 }else{ 15 this.name = name; 16 } 17 } 18 public String getName(){ 19 return this.name; 20 } 21 22 public void setHealth(int health){ 23 if(health < 0){ 24 System.out.println("健康值不合法."); 25 this.health = 0; 26 }else{ 27 this.health = health; 28 } 29 } 30 public int getHealth(){ 31 return this.health; 32 } 33 34 public void setLove(int love){ 35 if(love < 0){ 36 System.out.println("亲密度不合法."); 37 this.love = 0; 38 }else{ 39 this.love = love; 40 } 41 } 42 public int getLove(){ 43 return this.love; 44 } 45 46 public void setStrain(String strain){ 47 if(strain.equals("")){ 48 System.out.println("品种不能为空."); 49 }else{ 50 this.strain = strain; 51 } 52 } 53 public String getStrain(){ 54 return this.strain; 55 } 56 57 58 public Dog(){ 59 60 } 61 62 public Dog(String name,int health,int love,String strain){ 63 this.setName(name); 64 this.setHealth(health); 65 this.setLove(love); 66 this.setStrain(strain); 67 } 68 69 public void showInfo(){ 70 System.out.print("我的名字叫"+this.name); 71 System.out.print(",健康值"+this.health); 72 System.out.print(",亲密度"+this.love); 73 System.out.println(",我是一只"+this.strain); 74 } 75 }