java基础之封装
一、定义
封装就如其表面意思一样把东西包装起来,看不见里面的具体的细节只能看到外面一个大概的轮廓。在面向对象的编程语言中都支持封装的实现。在Java
中的封装就是把现实世界的物体抽象出共有的属性,然后在把这些属性封装起来,只是使用有限的方法
对这些数据进行操作。
二、样列
在二维平面中的图形,长方形通常都有一些共有的属性如:长
、宽
、面积
、周长
其具体的抽象如下:
public class Rectangle {
private Float length;
private Float width;
private Float circumference;
private Float square;
public Rectangle(Float length,Float width){
this.length = length;
this.width = width;
this.circumference = 2*(length + width);
this.square = length*width;
}
public void setCircumference(Float circumference) {
this.circumference = circumference;
}
public void setSquare(Float square) {
this.square = square;
}
public Float getCircumference() {
return circumference;
}
public Float getSquare() {
return square;
}
public void setLength(Float length) {
this.length = length;
}
public void setWidth(Float width) {
this.width = width;
}
public Float getLength() {
return length;
}
public Float getWidth() {
return width;
}
}
这样的抽象以及数据的封装看上去好像是正确的,但是我们仔细想一下会存在如下问题:
- 所有的数据都有
set
方法,看上去似乎非常的灵活便于修改,但是这也是不可控的因素。假如那天不小心在程序的某个地方修改了图像的面积,就会导致数据的不一致性。 面积
、周长
应该是我们在初始化的时候就应该计算完成,而不是由外部的调用方法set
改变数据。所以面积
,周长
不应该存在set
方法,不然会破坏数据的一致性。- 在重新设置长和宽的时候,由于长和宽的变化,会导致
面积
、周长
变化。
三、改进
基于上述的问题改进之后的代码如下
public class Rectangle {
private Float length;
private Float width;
private Float circumference;
private Float square;
public Rectangle(Float length,Float width){
if (length > 0 && width > 0){
this.length = length;
this.width = width;
this.circumference = 2*(length + width);
this.square = length*width;
}else {
throw new RuntimeException("长或者宽小于等于0,初始化失败");
}
}
public Float getCircumference() {
return circumference;
}
public Float getSquare() {
return square;
}
public void setLength(Float length) {
if (length > 0){
this.length = length;
this.circumference = 2*(length + width);
this.square = length*width;
}else {
throw new RuntimeException("重置长方形长度失败,参数小于等于0");
}
}
public void setWidth(Float width) {
if (width > 0){
this.width = width;
this.circumference = 2*(length + width);
this.square = length*width;
}else {
throw new RuntimeException("重置长方形长度失败,参数小于等于0");
}
}
public Float getLength() {
return length;
}
public Float getWidth() {
return width;
}
}
四、总结
说了这么多,也该说一下封装好处:
- 可以把修改数据的逻辑集中起来方便统一的管理,想一想代码的每一个角落里面都散落着对数据的修改逻辑这样代码维护起来肯定很不容易。
- 既然修改数据的代码是统一维护的,那就意味着我们对数据操作和修改是可以在我们控制范围之内,可控制性强,但是灵活性就没有那么强。
- 仅有几个简单的接口暴露出来操作数据,不需要了解里面操作细节,这样即使不熟悉业务流程的调用代码,出现错误的几率也会变低。原来没有封装之前在修改数据的时候需要了解计算细节,很容易出错。