Java封装的概念不是很清楚
我对封装概念有点困惑。我在同一个问题上回答了不少问题,但仍然感到困惑。据我所知,封装是将实例变量作为私有变量,以便外部无法直接访问。将提供公共getter和setter方法来访问私有变量。Java封装的概念不是很清楚,java,oop,Java,Oop,我对封装概念有点困惑。我在同一个问题上回答了不少问题,但仍然感到困惑。据我所知,封装是将实例变量作为私有变量,以便外部无法直接访问。将提供公共getter和setter方法来访问私有变量。 假设我们有一个如下所示的类: class Address { int doorNumber; public int getDoorNumber() { //some code } public void setDoorNumber(int doorN
假设我们有一个如下所示的类:
class Address
{
int doorNumber;
public int getDoorNumber()
{
//some code
}
public void setDoorNumber(int doorNumber)
{
//some code
}
}
我们有另一个类,试图从中访问Address类的变量
class TestAddress
{
public static void main()
{
Address add=new Address();
add.doorNumber=10; //cannot be done
add.setDoorNumber(10);
}
}
虽然我们没有直接访问变量,但我们仍然使用setter方法修改
doorNumber
,将其值设置为10。基本上,外部世界仍然可以访问私有字段,并以它想要的方式对其进行修改。我不明白封装有什么意义。你能给我一些例子来理解封装吗。还包括未使用封装的场景以及由此可能出现的问题。使用getter和setter比公开字段有一些好处:
intdoornumber来重新设计类的内部结构使用一个或多个可能不同类型的字段编码>。在这种情况下,可以保留getter和setter,这意味着不必修改其他类。如果您有首选的私有字段,则该类中的任何更改都将强制使用它的任何其他类中的更改
您可以在有效的Java项目14中了解更多信息,使用getter和setter比公开字段有一些好处:
intdoornumber来重新设计类的内部结构使用一个或多个可能不同类型的字段编码>。在这种情况下,可以保留getter和setter,这意味着不必修改其他类。如果您有首选的私有字段,则该类中的任何更改都将强制使用它的任何其他类中的更改
public class Address {
private int doorNumber;
public int getDoorNumber() {
return doorNumber;
}
public void setDoorNumber(int doorNumber) {
if (doorNumber <= 0) {
throw new IllegalArgumentException("door number must be > 0");
}
this.doorNumber = doorNumber;
}
}
public class Address {
private String doorNumber;
public int getDoorNumber() {
return Integer.parseInt(doorNumber);
}
public String getDoorNumber2() {
return doorNumber;
}
public void setDoorNumber(int doorNumber) {
this.doorNumber = doorNumber + "";
}
public void setDoorNumber(String doorNumber) {
this.doorNumber = doorNumber;
}
}
请注意,我们改进了API,以便能够表示地址,但仍然允许使用旧的“门牌号是整数”API。。。(有点)
但是如果doorNumber
是公开的,那么我们将被迫更改代码库中使用Address.doorNumber
的每个位置。考虑以下示例:
public class Address {
private int doorNumber;
public int getDoorNumber() {
return doorNumber;
}
public void setDoorNumber(int doorNumber) {
if (doorNumber <= 0) {
throw new IllegalArgumentException("door number must be > 0");
}
this.doorNumber = doorNumber;
}
}
public class Address {
private String doorNumber;
public int getDoorNumber() {
return Integer.parseInt(doorNumber);
}
public String getDoorNumber2() {
return doorNumber;
}
public void setDoorNumber(int doorNumber) {
this.doorNumber = doorNumber + "";
}
public void setDoorNumber(String doorNumber) {
this.doorNumber = doorNumber;
}
}
请注意,我们改进了API,以便能够表示地址,但仍然允许使用旧的“门牌号是整数”API。。。(有点)
但是如果
doorNumber
是公开的,那么我们将被迫更改代码库中使用Address.doorNumber
的每个地方。看看下面的反例:
class Address
{
int floor, door;
public int getDoorNumber()
{
return floor*100+door;
}
public void setDoorNumber(int doorNumber)
{
int newFloor=doorNumber/100;
if(newFloor<0 || newFloor>6)
throw new IllegalArgumentException("no such door "+doorNumber);
floor=newFloor;
door=doorNumber-newFloor*100;
}
类地址
{
室内地板、门;
public int getDoorNumber()
{
返回层*100+门;
}
公共无效设置门号(内部门号)
{
int NEWLOOR=门牌号/100;
如果(新楼层6)
抛出新的IllegalArgumentException(“无此类门”+门号);
楼层=新楼层;
门=门号新楼层*100;
}
}
调用setDoorNumber(10)
的代码仍然有效,无需任何更改。属性“doorNumber”独立于对象的内部表示,加上验证输入值的可能性,是封装的关键点。不能使用public int doorNumber这样的字段代码>
除此之外,还有开发人员考虑像setDoorNumber(int)
这样的方法与封装相矛盾,或者至少是一种弱封装形式。如果没有这样的public
setter方法,一个更强大的封装模型可以工作,但只提供高级操作。这样的操作,如在酒店预订房间,将执行更多相关操作,涉及其他对象,并在内部将房间号码分配给地址之前进行一致性检查…查看以下反例:
class Address
{
int floor, door;
public int getDoorNumber()
{
return floor*100+door;
}
public void setDoorNumber(int doorNumber)
{
int newFloor=doorNumber/100;
if(newFloor<0 || newFloor>6)
throw new IllegalArgumentException("no such door "+doorNumber);
floor=newFloor;
door=doorNumber-newFloor*100;
}
类地址
{
室内地板、门;
public int getDoorNumber()
{
返回层*100+门;
}
公共无效设置门号(内部门号)
{
int NEWLOOR=门牌号/100;
如果(新楼层6)
抛出新的IllegalArgumentException(“无此类门”+门号);
楼层=新楼层;
门=门号新楼层*100;
}
}
调用setDoorNumber(10)
的代码仍然有效,无需任何更改。属性“doorNumber”独立于对象的内部表示,加上验证输入值的可能性,是封装的关键点。不能使用public int doorNumber这样的字段代码>
除此之外,还有开发人员考虑像setDoorNumber(int)
这样的方法与封装相矛盾,或者至少是一种弱封装形式。如果没有这样的public
setter方法,一个更强大的封装模型可以工作,但只提供高级操作。这样的操作,如在酒店预订房间,将执行更多相关操作,涉及其他对象,并在内部将房间号码分配给地址之前进行一致性检查。setDoorNumber
有机会验证参数值并拒绝无效号码。进一步的