Java 关于用示例问题封装的问题

Java 关于用示例问题封装的问题,java,encapsulation,Java,Encapsulation,问题: 下面给出的类SmartPhone违反了封装规则。 重新写入,以便保留封装 我看不到任何其他破坏封装的规则,我记不起为什么这会破坏它 这是因为我们从该类外部返回另一个类的实例吗?在本例中,它的电池因此破坏了封装?封装意味着隐藏内部表示。需要删除任何显示实现的方法(尤其是getBattery())。我将从移除所有getter开始 class SmartPhone { private final Battery battery; private final String mak

问题:

下面给出的类SmartPhone违反了封装规则。 重新写入,以便保留封装

我看不到任何其他破坏封装的规则,我记不起为什么这会破坏它


这是因为我们从该类外部返回另一个类的实例吗?在本例中,它的
电池
因此破坏了封装?

封装意味着隐藏内部表示。需要删除任何显示实现的方法(尤其是
getBattery()
)。我将从移除所有getter开始

class SmartPhone {
    private final Battery battery;
    private final String make, model;

    public SmartPhone(String make, String model, Battery battery){
        this.make = make; this.model = model;
        this.battery = battery;
    }
}
这封装了手机实现的所有细节

然后,您应该添加表示手机应该显示的行为的任何方法,例如打开/关闭功能

在我看来,getter破坏了封装,但有时也没关系(比如
getMake()
getModel()
方法没有透露太多关于内部的信息)。您可以提供一种显示电压的方法,而不显示
电池
对象本身的详细信息。这是遵循以下原则


更新


封装是关于隐藏实现细节——“防止未授权方直接访问它们”()

公认的答案是错误的。通过封装的方式使电池不可变并没有任何作用,因为getter仍然使它对外部世界可见

您需要删除
getBattery()
方法,以便对
智能手机的用户隐藏实现细节


封装的好处是,它允许您稍后更改实现细节。如果你展示了
电池
,你以后就不能换用不同的电源,比如说
SolarPanel
,因为外界知道电池。

封装意味着隐藏内部表示。需要删除任何显示实现的方法(尤其是
getBattery()
)。我将从移除所有getter开始

class SmartPhone {
    private final Battery battery;
    private final String make, model;

    public SmartPhone(String make, String model, Battery battery){
        this.make = make; this.model = model;
        this.battery = battery;
    }
}
这封装了手机实现的所有细节

然后,您应该添加表示手机应该显示的行为的任何方法,例如打开/关闭功能

在我看来,getter破坏了封装,但有时也没关系(比如
getMake()
getModel()
方法没有透露太多关于内部的信息)。您可以提供一种显示电压的方法,而不显示
电池
对象本身的详细信息。这是遵循以下原则


更新


封装是关于隐藏实现细节——“防止未授权方直接访问它们”()

公认的答案是错误的。通过封装的方式使电池不可变并没有任何作用,因为getter仍然使它对外部世界可见

您需要删除
getBattery()
方法,以便对
智能手机的用户隐藏实现细节


封装的好处是,它允许您稍后更改实现细节。如果你展示了
电池
,你以后就不能换用不同的电源,比如说
SolarPanel
,因为外界都知道电池。

如果你对“封装规则”没有更清晰的定义,这个问题就有点模棱两可了。但我认为规则可能是(来自维基百科):

根据封装“可用于隐藏数据成员和成员函数”的定义,对象的内部表示通常在对象定义之外的视图中隐藏。通常,只有对象自己的方法才能直接检查或操作其字段。隐藏对象的内部可以防止用户将组件的内部数据设置为无效或不一致的状态,从而保护对象的完整性

根据该规则,对象应负责维护其自身的状态,包括作为其组件的任何其他对象的状态。如果不使用对象在其公共接口中提供的mutator方法,其他代码就不可能直接更改状态

因此,
SmartPhone
类违反了封装,因为它提供了对其内部
电池
组件的访问,该组件具有setter方法。如果我们认为电池的状态是电话内部状态的一部分(因为电池是电话的一个组成部分),那么电池的设定器方法允许内部状态的突变,而不是通过电话的变阻器方法。 有不止一种可能的解决方案。我的首选选项是使
电池
类不可变:

class电池{
私有最终字符串类型;
专用终端电压;
公共电池(串t,int v){type=t;电压=v;}
公共字符串getType(){return type;}
public int getVoltage(){返回电压;}
}
通过这种方式,
getBattery
方法可以自由返回对内部
battery
组件的引用,因为该电池没有突变方法,因此不会被其他代码突变

然而,这个问题有点暗示,智能手机类是你应该更换的,而不是电池类。也许出于其他原因,电池需要有setter方法。在这种情况下,问题更加微妙;按照当前编写类的方式,对内部
battery
对象的引用不仅可以通过
getBattery
方法获得,还可以通过首先构造对象时提供电池的人获得:

>电池b=新电池(
class SmartPhone {
    private final Battery battery;
    private final String make, model;

    public SmartPhone(String make, String model, Battery battery){
        this.make = make; this.model = model;
        this.battery = battery;
    }

    public String getMake(){
        return make;
    } 

    public String getModel(){
        return model;
    }

    public int getVoltage() {
        return battery.getVoltage();
    }
}