我对组合和封装的概念感到困惑。
这是帮助我瓶颈的例子: 我有一个A类,它有B和C类的部分.B也有D和E类型的部分。
class A
{
B itsB;
C itsC;
}
class B
{
D itsD;
E itsE;
}
class D
{
int mAlpha;
int getAlpha();
void setAplha(int);
}
A itsA;
对于这种情况,你如何只读访问mAlpha?
这样吗?itsA->getItsB()->getItsD()->getAlpha()
还是这样? itsA->getAlpha()
,其中A::getAlpha()
访问itsB->getItsD()->getAlpha()
写入访问mAlpha的方法怎么样?
这样吗?itsA->getItsB()->getItsD()->setAlpha(10.0)
还是这样? itsA->getItsB()->setAlpha(10.0)
,其中A::getAlpha()
访问itsB->getItsD()->setAlpha(10.0)
所以问题是;访问/修改复合类的各个部分,同时遵守封装原则,你应该只通过复合类的接口访问吗?
否则,似乎您在没有所有者组合的知识/许可的情况下访问该部件,进行修改。
请帮助我摆脱这种混乱
感谢。
答案 0 :(得分:0)
所以问题是;访问/修改复合类的各个部分,同时遵守封装原则,你应该只通过复合类的接口访问吗?
根据封装原理,应隐藏复合材料的部件。假设mAlpha
在逻辑上是 A
的属性,但在{/ em> D
中实现,则应在{{1}中添加访问者方法查找/更改其A
部分中的mAlpha
成员。否则,您将泄露D
的实现细节(它是A
和其他一些东西的组合。)
答案 1 :(得分:0)
我会让A
通过公开自己相同的方法名称和签名来委托对getAlpha()
的访问权。
class A
{
public:
int getAlpha()
{
return itsB.getAlpha();
}
};
class B
{
public:
int getAlpha()
{
return itsD.getAlpha();
}
};
虽然这会使代码变得复杂,但您应该考虑更改封装职责的方式。
答案 2 :(得分:0)
对于这种情况,你如何只读访问mAlpha?
这样吗? itsA-> getItsB() - > getItsD() - > getAlpha()还是这样? itsA-> getAlpha(),其中A :: getAlpha()访问其B-> getItsD() - > getAlpha()
这有点复杂,因为你必须尊重两种封装级别。 据推测,B被用作混合来实现A,因此您可能希望B成为A的私有成员,从而消除了第一种方法的可能性。第二种方式隐藏了A中B的存在,并且允许从A中实现一些合同,关于它允许对其进行B的操作。你可以在B和D之间将相同的事物分层,而不是只是提供一个指向D的指针并抓住Alpha视图,但是在B的实现中私下使用D。你最终会用相互调用的方法层,并且在简单的情况下它似乎效率低下,但它是关于什么是客户端A知道它的实现,以及B的客户知道B的实现。
从这个思想角度来看,你的第一行是写的,这样A的消费者必须知道它的内部结构才能获得Alpha值。它必须知道那里有一个带有Alpha的D。为了允许更改A的实现,您可以隐藏像getAlpha()这样的函数后面的细节。然后是B的同样的事情。
HTH
-Chris
答案 3 :(得分:0)
我将“封装”更多地作为一般概念。类具有多个字段,属性,方法,被视为单个项目,这些成员是公共的,私有的或受保护的。对于“封装”,对象是否包含其他对象并不重要。
class CarClass {
private: double InitialPrice;
protected: WheelClass wheels[4];
protected: MotorClass motor;
public: turnOn();
public: turnOff();
}
这里,“封装”的意思是,让我们把这个字段,简单的数据类型或对象,这个方法,并将它们全部放到一个实体中。
对于“复合类”或“复合对象”,我将其作为对象,将其他对象作为其一部分。类或对象负责创建或销毁这些子元素对象。如果一个类有指针或引用其他对象,但它不负责删除或添加它们(在内存中分配),那么它不是复合的。
class SpaceShipClass {
SpaceShipClass() {
this.engine = new EngineClass();
this.wings = new WingClass();
}
~SpaceShipClass() {
free this.engine();
free this.wings();
}
private: EngineClass engine;
protected: WingsClass wings;
public: PilotClass pilot;
public: Fly();
public: Landing();
}
在前面的例子中,“引擎”& “翅膀”使“SpaceShipClass”成为复合类。但是,该领域的“飞行员”,并不是因为它不属于“类”,它只是有一个参考。
检查我没有使用类成员作用域(私有,受保护或公共)作为与“封装”或“组合”概念相关的内容,它是O.O.P.的一部分,但它不需要它用于封装或组合。事实上,有O.O.编程语言,其中所有成员都是公共的,并且仍然可以具有封装或组合类。
使用“参考”编程语言,使初学者更难理解“课堂作文”。