封装
封装是把抽象的数据(也就是属性)和对数据的操作(也就是方法)封装在一起,数据被保护在内部,程序的其他部分只有通过被授权的操作,才能对数据进行操作。
下面我们用一个小程序来做演示。
该程序是设置学生的姓名,年龄及成绩。其中年龄和成绩设为私有。我们还需要对设置的年龄进行判断,合理即赋值,不合理给出提示并且赋予默认值。
如何实现封装呢?
1、对属性进行私有化(private)
2、提供一个公共的(public)set方法,用于对属性进行判断及赋值
3、提供一个公共的(public)get方法,用于获取属性的值并且返回其值
class Student{
public String name;
private double score;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
封装的好处
1、可以隐藏实现细节
2、可以对数据进行验证,保证数据安全且合理
我们可以看下面这个代码
public class Encap {
public static void main(String[] args) {
Student student = new Student();
// student.name = "Lydia";
//student.age = 18;
//我们是不能像上面这样给age赋值的,因为age被私有化,是不可以直接赋值的
student.setName("张三");
student.setAge(18);
student.setScore(100);
System.out.println(student.info());
System.out.println("===========");
student.setName("李四四四四");
student.setAge(200);
student.setScore(85);
System.out.println(student.info());
}
}
class Student{
public String name;
private double score;
private int age;
//一个无参构造器
public Student() {
}
//一个又参构造器
public Student(String name, double score, int age) {
this.name = name;
this.score = score;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
//对数据进行验证
if( name.length() >1 && name.length() <= 4) {
this.name = name;
}else {
this.name ="无名";
System.out.println("名字的长度需在2-4个字之间");
}
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if(age<120){
this.age = age;
}else {
this.age=0;
System.out.println("年龄需在(1-120),请重新输入");
}
}
//写一个将信息输出的方法
public String info(){
return "信息为 name=" + name + " age=" + age + "岁" + " 成绩为" + score + "分";
}
}
可以看到输出为:
如果用构造器该怎么办?
很多时候,我们为了方便,会用构造器指定属性
//一个无参构造器
public Student() {
}
//一个又参构造器
public Student(String name, double score, int age) {
this.name = name;
this.score = score;
this.age = age;
}
但当我们用构造器直接给属性赋值,运行之后我们会发现,跳过了对属性的值判断的过程
public class Encap {
public static void main(String[] args) {
Student student = new Student();
// student.name = "Lydia";
//student.age = 18;
//我们是不能像上面这样给age赋值的,因为age被私有化,是不可以直接赋值的
student.setName("张三");
student.setAge(18);
student.setScore(100);
System.out.println(student.info());
// System.out.println("===========");
// student.setName("李四四四四");
// student.setAge(200);
// student.setScore(85);
// System.out.println(student.info());
Student student1 = new Student("李四四四四",85,200);
System.out.println(student1.info());
}
}
运行结果:
我们可以看到结果直接输出,并没有给值进行判断,那我们该如何解决这个问题呢?
我们可以将构造器和setxxx相结合
//将构造器和setxxx相结合
/*
当我们将set写在构造器当中时,每一个赋予的值都会被进行判断
*/
public Student(String name, double score, int age) {
setScore(score);
setName(name);
setAge(age);
}
此时我们再次运行程序,我们可以得到以下输出: