封装的思想
在定义一个学生类并使用的时候,发现了一个问题:通过对象给成员变量赋值的时候,可以赋值一些非法的数据。这样是不合理的、不符合现实生活的。我们应该在赋值之前,做一次判断,即数据校验,也就是对即将要赋值的数据做判断。
那么又出现一个问题:我们应该在哪里定义这个判断逻辑呢?该代码来看,StudentDemo2是一个测试类,一般情况下,测试类是负责创建对象并使用对象的地方,在这里定义不合适。所以应该定义在Student3类中,又因为定义成员变量的时候无法加入判断逻辑,所以我们在Student3类中提供一个方法来定义逻辑判断。如果符合则成功赋值,反之则不赋值。
class Student3 {
//定义成员变量
String name;
private int age;
public void setAge(int a) {
if (a < 0 || a > 200) {
System.out.println("您要传入的年龄数据有误,请重新赋值");
} else {
age = a;
}
}
//定义一个方法输出所有的成员变量
public void show() {
System.out.println("姓名:" + name);
System.out.println("年龄:" + age);
}
}
public class StudentDemo2 {
public static void main(String[] args) {
//创建一个学生对象
Student3 s = new Student3();
s.show(); //null,0
//给对象的成员变量赋值
s.name = "小明";
s.setAge(1000);
s.show();
}
}
但是,问题又来了:谁规定了我们定义了一个方法就一定会被使用呢?如果还是通过对象给成员变量赋值,问题还是存在。那么我们给出的方法意义就不是很大。
实际上,我们应该定义了一个方法后,让调用者必须使用我们的方法进行赋值,并且不能让调用者直接获取到我们的成员变量。
针对这样的情况,java提供了一个关键字——private
封装概述
1.封装概述:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式
2.好处:
隐藏实现细节,提供公共的访问方式
提高了代码的复用性
提高安全性
3.封装原则:
将不需要对外提供的内容都隐藏起来
把属性隐藏,提供公共方法对其访问
private关键字
1.private关键字:
是一个权限修饰符
可以修饰成员(成员变量和成员方法)
被private修饰的成员只在本类中才能访问
2.private最常见的应用
把成员变量用private修饰
提供对应的getXxx()和setXx()方法
一个标准的案例的使用
获取成员变量值得方法:
1)提供一个公共的方法,打印所有的成员变量值
2)单个使用公共的获取方法,一个一个的获取打印(开发时使用最多,单个使用比一起使用的灵活度高)
规范定义一个类的标准版本1.0
1.将成员变量使用private修饰
2.提供getXxx()和setXxx()方法
3.提供一个方法打印所有的成员变量值(先自己定义,后面我们会学习新的方法替代)
class Phone2 {
//定义成员变量
private String brand;
private int price;
private String color;
//提供公共的getXxx()和setXxx()
public void setBrand(String s) {
brand = s;
}
public String getBrand() {
return brand;
}
public void setPrice(int a) {
price = a;
}
public int getPrice() {
return price;
}
public void setColor(String s) {
color = s;
}
public String getColor() {
return color;
}
//提供一个方法打印手机详情
public void show() {
System.out.println("品牌:" + brand + ",价格:" + price + ",颜色:" + color);
}
}
public class PrivateTest {
public static void main(String[] args) {
//创建一个对象
Phone2 p = new Phone2();
//给成员变量赋值
p.setBrand("一加");
p.setPrice(3999);
p.setColor("紫色");
//获取成员变量并打印
String brand = p.getBrand();
int price = p.getPrice();
String color = p.getColor();
System.out.println(brand + "----" + price + "----" + color);
//调用方法打印所有的成员变量值
p.show();
}
}
this关键字
回想我们之前定义变量的时候,提出一个规范:见名知意。我们根据见名知意的规范来重新定义形参的名字,运行后发现结果不对,值没有赋上。这是因为局部变量的使用规则:就近原则,这里的name使用的都是形参的变量名name,没有使用成员变量值name。我们理想上应该是将传进来的name赋值给调用该方法的对象的成员变量name
java提供了一个关键字:this
this:代表所在类的对象引用
注:方法被哪个对象调用,this就代表哪个对象
什么时候使用this关键字?
局部变量隐藏成员变量
(其他用法后面和super一起总结)
class Doctor {
private String name;
public void setName(String name) {
// name = name; 这样赋值失败
// Doctor.name = name; 通过 类名.成员变量 的方式目前也是不行的
this.name = name;
}
public String getName() {
return name;
}
}
public class DoctorDemo {
public static void main(String[] args) {
//创建一个医生对象
Doctor d = new Doctor();
d.setName("林巧稚");
}
}
规范定义一个类的标准版本2.0
1.将成员变量使用private修饰
2.提供getXxx()和setXxx()方法,形参的名字与成员变量名字一样,使用this关键字赋值
3.提供一个方法打印所有的成员变量值
class Doctor2{
private String name;
private int age;
private String gender;
public void setName(String name){
this.name = name;
}
public String getName() {
return name; //其实这里隐藏了一个this,但是我们也可以不写,因为就近原则取的就是对象的成员变量
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getGender() {
return gender;
}
//提供一个公共的方法
public void show() {
System.out.println("姓名:" + name + ",年龄:" + age + ",性别:" + gender);
}
}
public class DoctorDemo2 {
public static void main(String[] args) {
//创建一个医生对象
Doctor2 d = new Doctor2();
//给成员变量进行赋值
d.setName("小明");
d.setAge(18);
d.setGender("男");
d.show();
}
}