英文:
Where would a sortedSet go in this UML diagram?
问题
我正在通过一本关于Python数据结构的书来自我学习,遇到了有关继承章节的练习问题。我感到非常困惑。
问题:
一个已排序的集合的行为就像一个集合,但允许用户使用for循环按升序访问其项目,并支持对项目的对数搜索。绘制一个类图,显示您将在下面的图中的集合框架中放置一个新的已排序集合类的位置:
我不确定新的已排序集合类在这个图中应该放在哪里。我的直觉告诉我,它可能会被添加为第三个"bag"接口?例如,LinkedBag、ArrayBag和一个新的SetBag都指向bag接口和抽象bag,而SetSortedBag指向SetBag?
这样做对吗?我觉得这个问题有点奇怪。
英文:
I am self guiding myself through a Python Data Structures book and came across this problem for one of the exercises regarding the chapter regarding inheritance. I am very puzzled.
The problem:
A sorted set behaves just like a set, but allows the user to visit its items in ascending order with a for loop, and supports a logarithmic search for an item. Draw a class diagram that shows where you would place a new class for sorted sets in the collection framework shown in the figure below:
I am confused on where a new class for a sorted set would go in this diagram. My gut tells me, it would be a be added as a third bag interface? For example LinkedBag, ArrayBag and a new SetBag point to bag interface and abstract bag, and SetSortedBag points to SetBag?
Is this on the right track? I find this question sorta odd.
答案1
得分: 2
假设"LinkedBag"指的是链表数据结构,那么是的,你说得对,"Set"应该是第三部分,而"SortedSet"则从它继承。然而,我不会将它定义为一个"接口"。
接口是一种类的类型,通常用作继承类要遵循的蓝图,并不实现它们自己的类函数。相反,它们声明其派生类将实现的函数。有关额外信息,抽象类类似,不过它们可以实现自己的类函数。通常情况下,接口和抽象类都不能初始化为对象。在Python中,这一点变得更加模糊,因为Python使用一般的"Python抽象基类",而不是直接使用接口,但可以通过抽象类来模拟。然而,在一般编程术语中,普通类、接口和抽象类之间的区别可能很重要,尤其是因为接口和抽象类通常不能被初始化为对象。关于接口和抽象类的继承规则可能在不同的编程语言中有所不同,例如在Java中,你不能从多个抽象类继承,所以我不会在这里直接讨论它。
由于"Set"是一个独立的数据结构,通常应该具有与排序集不同的功能,所以你不应该将"Set"定义为一个接口,而是一个普通类。你仍然可以从普通类继承,这就是"SortedSet"从"Set"继承的方式。
英文:
Assuming that LinkedBag refers to the LinkedList data structure, then yes you are correct in that Set would be a third section, with SortedSet inheriting from it. However, I would not define it as an "interface".
Interfaces are a type of class which is generally used as a blueprint for inheriting classes to follow, and does not implement their own class functions. Instead, they declare functions which their derivative classes will implement. For additional information, Abstract Classes are similar, except that they can implement their class functions. Neither Interfaces nor Abstract classes can (usually) be initialized as an object. This becomes a lot more blurry in Python which uses the general "Python Abstract Base Classes" and doesn't do Interfaces directly, but can be mocked through the abstract classes. However, as a term for general programming, the distinctions between normal classes, interfaces, and abstract classes can be important, especially since interfaces and abstract classes (usually) are not/ can not be initialized as objects. The exact rules of inheritance regarding Interfaces and Abstract Classes can differ between languages, for example in Java you can't inherit from more than one abstract class, so I won't directly address it here.
Since a Set is a data structure on its own that can, and usually should, have functionality separate from a sorted set, you would not make the set an interface, but rather a normal class. You can still inherit from normal classes, which is what you would do with SortedSet inheriting from Set.
答案2
得分: 0
按照叙述的内容,一个排序集(sorted set)就像一个集合(set),但在某些行为上有一些变化:
排序集的行为与集合相同,但允许用户使用for循环以升序访问其项,并支持对项进行对数级搜索。
这意味着SortedSet
会继承自Set
,就像SortedArrayBag
继承自ArrayBag
一样。继承应该在UML中以一个大的空心箭头(就像你的图中那样的小箭头表示可导航关联,与继承无关)来表示。
但是,集合不是袋子。集合最多包含一次项目,而袋子可以包含多次相同的项目。这可能会导致完全不同的接口(例如,对于集合来说,项目的成员是一个布尔值,而对于袋子来说,可以是一个整数)。因此,一个安全的方法是插入一个继承自AbstractCollection
的AbstractSet
:
一个快捷方式可以是像对待袋子一样对待集合,并对属于集合的任何项返回1的计数,忽略多次插入。这将不符合Liskov替代原则,因为它不会遵守所有不变量并减弱后置条件。
但如果你仍然选择这种方式,你应该将Set
插入为扩展AbstractBag
,将SortedSet
插入为Set
的特化。在这种情况下,你的集合(和排序集)也将实现BagInterface
(即使它会扭曲它)。Shorn的回答 很好地分析了这种情况。
英文:
A sorted set according to the narrative is a set, but with some variations in some behavior:
> A sorted set behaves just like a set, but allows the user to visit its items in ascending order with a for loop, and supports a logarithmic search for an item.
This means that SortedSet
would inherit from Set
, just like SortedArrayBag
inherits from ArrayBag
. Inheritance should by the way shown in UML with a big hollow array head (small arrows like in your diagram mean a navigable association, which has nothing to do with inheritance).
A set is however not a bag. A set contains an item at maximum once, whereas a bag may contain multiple times the same item. This could lead to a completely different interface (e.g. membership on an item is a boolean for a set, whereas it could be an integer for a bag). The safe approach would therefore be to insert an AbstractSet
inheriting from AbstractCollection
:
A shortcut could be to deal with the set like a bag, and return a count of 1 for any item belonging to the set, ignoring multiple inserts. This would not be compliant with the Liskov Substitution Principle, since it would not respect all the invariants and weaken post-conditions.
But if you'd nevertheless go this way, you should insert Set
as extending AbstractBag
, and SortedSet
as a specialization of Set
. In this case, your set (and sorted set) would also realise the BagInterface
(even if it'd twist it). Shorn's answer analyses this situation very well.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论