工作中用C#开发,目前自学Java。自以为很理解Java中的getter
和setter
了,结果被朋友一问,发现还是一知半解,越想越懵逼。
问题主要有两个:
1. Java中为什么要用getter
和setter
处理private field,而不直接把它设为public,以供外边的class用呢?
以Student类为例,以下是Java代码。
public class Student
{
private String name;//学生姓名
private int grade;//学生成绩
//getter
public String getName()
{
return name;
}
public int getGrade()
{
return grade;
}
//setter
public void setName(String name)
{
this.name = name;
}
public void setGrade(int grade)
{
this.grade = grade;
}
}
这是最常见的写法,称为JavaBean。
读了一篇博文后,我很受启发,推荐给大家:关于面向对象编程中很多人用get()和set()方法,而不用public的一点总结
然后通过和朋友讨论,我总结了四点用getter
和setter
的优势。
a. 减少代码的重复性:
设想在调用Student的其他几个地方,都要对学生的grade
进行加10操作。如果grade
是public member,每个类中都要对grade
加10。而如果用setter
,只在Student类中对grade
加10,其他地方只需要调用Student中的setGrade
就可以了。
b. 减少异常事件:
假如学生的grade
数值范围是0到100,如果将grade
设为public,那么Student类以外的用户很可能会输入0-100以外的数字。而如果在setGrade
中加以限制,就能减少exception的发生。
public void setGrade(int grade)
{
if(grade>=0 && grade<=100)
this.grade = grade;
else
System.out.println(
"Please type in an integer between 0 and 100");
}
c. 封装:
Java中引入getter
和setter
的主要目的在于遵循面向对象编程的一大特性——封装。
想来这是合理的,学生的name
及grade
本来就是学生本身的属性,需要进行什么修改,拥有什么样的逻辑,本来就应该在Student类里进行,而不应该由外界控制。
d. 减少内存占用:
我们都知道,要根据一个变量的作用域设置它的权限修饰符(public, private, protected…)。如果把grade
设为public, 它将存在于整个程序运行周期,而设为private,它只在调用Student类时存在。从这点来看,当然是设为private最好啦。
2. 类似Java的getter
和setter
,C#中get
和set
是怎么用的呢?
还是以Student类为例,以下是C#代码。
public class Student
{
private string name;//学生姓名
private int grade;//学生成绩
public string Name
{
get { return name; }
set { name = value; }
}
public int Grade
{
get { return grade; }
set { grade = value; }
}
}
在这里,Name和Grade被称为property,是暴露给外面的属性。在Student类内部,通过get
和set
可以对其private field进行读和写操作。
感觉C#里的get
和set
更好理解有木有,就好像把Java中的name
和grade
直接设为public了。
Student student = new Student();
student.Name = "小明";
student.Grade = 95;
可能是我C#用的多,比较习惯了⚆_⚆