这是我天真的思考过程。当有人指出任何差异时,我感激不尽。
我知道在Java中可以创建私有嵌套类。但是在PHP中(称自己为“OOL”)并不容易实现这样的事情。
但是,我可能需要在只有一个其他类中使用辅助类。
这自然导致我考虑使用我认为它应该实际解决这类问题的构图,原因如下:
- 如果它引用的对象,它只被称为复合 真的是它的部分,即没有独立的存在。
- 聚合与普通组成的不同之处在于它并不意味着所有权。 在构图中,当拥有对象被破坏时,它也是如此 包含的对象。在汇总中,这不一定是真的。
因此,在组合中,组件不应该在没有其他组合对象的情况下存在,我假设基本上只有一种方法可以通过使用私有嵌套类,否则我需要让 Component类可见,使其在其他地方也可以实例化,违反复合内的组件创建/销毁 - 班rule。
现在我遇到了PHP,根本不可能创建嵌套类(或者可能有一些魔法),这可能会导致一个问题,为什么我们需要嵌套类呢?
Compelling reasons for using nested classes include the following:
这是一种逻辑分组仅在一个中使用的类的方法 place:如果一个类只对另一个类有用,那么它就是 合乎逻辑地将它嵌入该类中并将两者保持在一起。嵌套 这样的“帮助班”使他们的包更加简化。
它增加了封装:考虑两个顶级类A和B, 其中B需要访问否则将被声明的A成员 私人的。通过在B类中隐藏B类,可以声明A的成员 私人和B可以访问它们。另外,B本身可以隐藏 来自外部世界。
它可以带来更易读和可维护的代码:嵌套小 顶级类中的类使代码更接近它所在的位置 使用
所以在我看来,随着嵌套类增加封装(从而允许实现复合概念),应始终可以在适当的OOL中创建嵌套类。
我也查阅了OOP的定义,它只提到了对封装,抽象,继承,多态概念的支持。
封装意味着对象的内部表示通常隐藏在对象外部的视图中 定义
抽象是根据接口和功能开发类,对象,类型,而不是实现细节。 (例如,相反或创建一个命令序列来处理半径和点,我们将抽象出一个圆的概念。所以我们定义一个类Circle及其属性/函数,使其反映这个抽象概念。)
继承应该是抽象之间的 is-a 关系(允许代码重用)。
多态性允许覆盖和重载方法。
一个人问了一个问题here,它实际上完全符合我对问题的理解,恕我直言得到了相当不准确的答案,被告知真的很困惑,并提供了一个代码样本,IMO不是一个合适的组成,因为它在PHP中实际上是不可能的。此外,有人可能会说组成不是关于内部阶级。
我是否理解了一些真正的错误?
答案 0 :(得分:3)
composition 等概念是通用的,它们的实现可能因编程语言而异。
另一方面,我不会说包含 [...]的组合的定义没有独立存在是指能够创建实例或者不是来自不同的范围。
没有独立存在是一个概念性而非实际的规则。这意味着 wheel 永远不会是组合根,因为 root 是汽车。也就是说,一个轮子不能独立于汽车存在。
因此,结论是嵌套类只是一个实现细节,它们与组合无关。请注意,对象不是从所有编程语言中的类创建的,但仍然可以使用组合和许多其他功能。你会说JavaScript中的对象组合是不可能的吗?
var car = { manufacturer: "Ford", model: "Focus" };
// I can create the wheel after the car
var wheel = { color: "black" };
// but it'll be always tied to some car
car.wheel = wheel;
无论如何,几乎所有系统都实现聚合,这是组合的一种风格。在软件工程上查看this Q&A。
虽然车轮在没有汽车的情况下是无用的,但车轮仍然作为汽车制造的许多机械部件之一被拆开,因此 wheel 可以独自生活,但它只是一块没用。
OP过于关注并关注UML组成的正式定义:组合,关联,直接关联,聚合......
顺便说一下,OOP中的术语组成具有更常见的含义,例如,在讨论何时使用继承或何时避免使用时,我们谈论composition over inheritance 。例如,参见2010年的Q& A:What is composition as it relates to object oriented design?基本上所有的回答者都对组成的定义达成了共识。在一天结束时,术语组合是创建对象图的方法:将简单类型关联在一起以创建更复杂的类型。
因此,正如我在本答案的第一部分已经解释的那样,嵌套类只是一种编程语言实现细节,它们对于实现任何组合风格并不重要。
但从概念上讲,为了正确地实现它作为一个组合, 我更喜欢像部分类(如在C#中)那样的东西 将代码分成多个文件但限制了实例化 仅限主要课程。我知道你不同意我的意见,我必须这样做 以某种方式表达我的观点。
这是一个错误的例子,因为 partial classes 只是粘合定义同一个类的多个文件的语法糖,后来一切都是同一个类。
C#有嵌套类:
public class A
{
public class B
{
}
}
但是您需要从概念的角度理解类型定义与对象无关,因为面向对象的语言可能会也可能不会有类型系统和类,但它可以支持组合及其所有风格。
答案 1 :(得分:0)
在维基百科中,还有以下组合示例,而不使用私有嵌套类。
class University
{
std::vector<Department> faculty; //this is composition
std::vector<People*> people; //this is aggregation
University() // constructor
{
// Composition: Departments exist as long as the University exists
faculty.push_back(Department("chemistry"));
faculty.push_back(Department("physics"));
faculty.push_back(Department("arts"));
}
};
对于真实的作文,只要我们对部门的实例进行适当处理,我们就不必将整个班级设为私人,即我们需要确保在大学不再存在时实际删除所有部门。
在JavaScript中实现不同组合的类似方法如下:
/*this is a component's "class"*/
function Text(txt){
this.txt = txt;
}
/*this is a composite's "class"*/
function Hello(begining){
/*public object*/
this.begining = begining;
/*this is like making an instance from a nested function which is a composite*/
var Middle = new (function Middle(txt){
this.txt = txt;
})(" - ");
/*private object - also a composite, even though it's made of the public class Text*/
var Ending = new Text("that's all.");
/*The use of the private property Ending*/
this.Say = function(){
var msg = this.begining.txt + Middle.txt + Ending.txt;
console.log(msg);
}
}
/*
This txt variable will be the "begining" text. It could still be a composite, but
only if it's not used in another composite when purpose is to be
"an untransferable part" and not a "visitor".
*/
var txt = new Text("Dan");
var say1 = new Hello(txt);
var say2 = new Hello(new Text("To be or not to be"));
say1.Say() /*Dan - that's all.*/
say2.Say() /*To be or not to be - that's all.*/
但是,当人们看到&#34;汽车&#34;时,即使是可转让性也常常是一个被忽视的规则。拥有&#34;轮子&#34;作为部分(而不是&#34;访客&#34;)
而不是&#34;神经网络&#34;和#34;神经元&#34;或&#34;森林&#34;和&#34;树&#34;。树木不经常重新种植到不同的森林。
由于车轮仍然可以被理解为复合材料的一部分,因此它不必与代码中的聚合不同。