我被告知根据以下代码示例开发我的代码:
Class Dogs{
List<Dog> listOfDogs = new ArrayList<Dog>();
// Setters, getters...
}
Class Dog{
// Attributes and methods
}
问题是:为什么将Dogs
类实现为Dog
对象的ArrayList的容器更好,而不是仅仅引用一个简单的ArrayList。
这被认为是封装吗?
答案 0 :(得分:4)
我认为没有理由创建一个单独的Dogs
类,除非除了添加,删除和访问成员的标准集合操作之外还要在Dogs
上执行其他操作。例如,如果有releaseTheHounds()
方法或callEveryoneForDinner()
方法等,
但是,可能是您被告知的是,您应该使用List
类型来声明listOfDogs
,而不是ArrayList
。就是这样:
List listOfDogs = new ArrayList<Dog>();
而不是:
ArrayList listOfDogs = new ArrayList<Dog>();
你已经这样做了,这是一个很好的做法。这里,“封装”是隐藏ArrayList
作为List
接口的实现者。这样可以轻松切换到其他实现(例如TreeList
),而无需更改访问listOfDogs
的任何代码。
最后但并非最不重要的,你真的应该这样声明:
List<Dog> listOfDogs = new ArrayList<Dog>();
然后,您确保List
保留Dog
个实例,而不是其他任何内容。
答案 1 :(得分:4)
我可以看到为什么有人要求你这样做,尽管就像其他答案所暗示的那样,这是一个过于宽泛的问题无法正确回答。取决于场景。
现在,这里的理由可能是当你有一个Dog对象的容器时,你可以控制如何创建,访问和更改这些对象。如果你只有一个列表,你无法真正控制正确的访问或添加/删除操作。但是,如果你有狗类。您可以返回只读列表,不允许添加特定品种的狗等。它基本上可以作为所有与狗有关的控制器类。
Class Dogs
{
List listofDogs = new ArrayList<Dog>();
public void AddDog(Dog newDog)
{
//check if valid
}
public List<Dog> getDogs()
{
//return readonly dogs collection
}
}
答案 2 :(得分:4)
基本上,创建Dogs
类可为您提供额外的间接层。
这意味着您的所有其他代码将仅引用(即使用)Dogs
类,而不引用内部列表。反过来,这意味着无论何时您决定从使用列表切换到内部使用普通数组(或以任何其他方式更改Dogs
的实现),您都可以随便这样做。
这是它的动力。至于它是否更好等问题,这在很大程度上取决于您是否可以通过稳定的Dogs
API来限制内部容器的使用。如果可以,创建Dogs
类是合理的。否则,只需继续使用List
即可。更简单,更容易。
上述稳定API的一个例子&#39;是访客模式的应用程序。在这种情况下,Dogs
类应该有一个visit()
方法接受访问者参数。访客&#39;知道&#39;如何处理Dog
,但完全不知道Dogs
内部结构。这是件好事。
答案 3 :(得分:1)
使用我使用的mvc框架
使得对webforms的序列化更容易一些答案 4 :(得分:1)
这取决于您的问题以及您要对该数组列表执行的操作。您可能希望扩展ArrayList的某些操作或添加将应用于所有数组列表项的新操作,例如对方法进行排序此列表按顺序排列。
答案 5 :(得分:0)
我相信他们可能希望你们做一些类似“对象池模式”的事情。对象池设计模式是一种创建设计模式,可以在处理实例化缓慢的类时提高性能。不是构造新对象,而是根据需要从池中检索可释放对象并将其释放到池中。
在这种情况下,Dogs将成为Pool,Dog将成为PooledObject,并且任何使用PooledObject类型对象的类都将成为客户端。
答案 6 :(得分:0)
当我们有一组对一组对象典型的方法时,我们使用这样的实现。因此,我们不关注特定的表示选择,而是关注共享的操作和属性。例如,堆栈使用此模式,堆栈上通常可用的操作如下:push,remove,确定堆栈是否为空等等。而不是Dog,它使用Object;所以你可以堆叠任何对象。
现在你可以添加除Dog以外的对象,它们将共享相同的方法。