I'm a bit confused regarding Generalization, Aggregation and abstract classes in UML.
By Generalization, I can understand that it's a "is a"-relationship. A student is a Person - and a teacher is a Person. So Person would be the superclass, whereas student and teacher are both subclasses.
By Aggregation, this is what I understand: It's a "softer" relation compared to composition. An example could be: You can have a hand with no fingers (aggregation) but you can't have fingers without a hand (composition).
And then I am completely lost on abstract classes. What are the characteristics of abstract classes? I'd like an example on this if possible.
But am I on the right track here? This is how I understand these terms.
You understand Generalization.
Associations may be Aggregations or Compositions (or neither). This is a good example that Tom Pender used to use. Suppose you have a Car class. That Car class "has" a steering wheel, seats, two axles, four wheels, and so on. If you're creating that Car in a manufacturer context, the relationship between all of those would be Composition: the lifetime of all the car's parts (at your manufacturer) is tied to the lifetime of the car. From the standpoint of the manufacturer, the lifetime of the car and all its parts ends when you deliver it to a dealer.
Now, let's suppose you're the owner of a junkyard. In this case, a car still "has" all those parts, but they have a lifetime of their own: you can sell parts off of the car, and even make them part of some other car if you need to. The relationship between the car and those parts is Aggregation, because the lifetime of the parts isn't tied to the lifetime of the car itself.
So, you can see that the same car could actually be modeled in two different ways depending on context.
As for abstract classes: an abstract class is simply a class that defines methods and/or properties while requiring that they can only be implemented in subclasses. It's easiest to explain why with interfaces. Interfaces are abstract classes, with the added proviso that NONE of the methods or properties can be implemented directly in the class (you might say it's a definition of how to define a subclass). Here's where they come in useful.
Suppose I want to define an Animal class. What do animals do? Well, they move. They bite. (They do other things too, of course, but let's stick to Move and Bite.) If I create an Animal interface, I'm saying "here's what an animal does. If you want to be an animal, you have to also do these things. However, I'm not going to tell you how to do them." So, I create an iAnimal interface, with two methods, Move and Bite. As an interface, I don't provide any sort of implementation, just empty procedures.
Now, suppose I have two animals, a Flea and a TRex. Clearly, Fleas and TRexes don't have anything in common in the way that they move or the way that they bite, but they both do both. I'll have Flea and TRex inherit or "implement" the interface, providing implementations of Move and Bite appropriate for the type of animal.
The advantage of this is that clients of my flea and trex don't have to know which one they are dealing with. They can create an iAnimal, inject an instance of Flea or TRex as appropriate, and safely call iAnimal's Move and/or Bite methods without having to worry about whether they're supported or not. (This is what we mean by "polymorphism").
So, interface implementation is a form of Generalization (more correctly Specialization, going the other way), as you have probably already surmised.
From here, an "abstract class" is simply any class with any method or attribute defined that has to be inherited to be implemented. Therefore, as I have said, interfaces are abstract classes. However, in general usage, an abstract class is taken to mean one that is not also an interface, i. e. one that has some concrete methods or attributes. Most programming languages adhere to this definition.
Related
In my case, what is appropriate relationship between CarBuilder and SuperCar (SportCar as well)?
Explanation: CarBuilder holds an array of Car class's instance but it doesn't construct any instance of Car class. Instead, it constructs SportCar, and SuperCar classes' instances by directly call CreateInstance() method of these two classes.
Class Diagram:CarBuilder
In your question you are describing three different relationships -- a compositional one (that you already have), and then two others to the constructors of SuperCar and SportCar. So I'd just add an association to SuperCar and SportCar from CarBuilder.
Incidentally, it seems unlikely that you'd only ever have a car composed within CarBuilder -- maybe you mean a (weak) aggregate rather than a composition? Surely a car can exist outside CarBuilder? Also, this looks like a partial implementation of the strategy pattern, might be worth looking whether that's relevant.
Let's say I have class Foo that has an association to some thing(s) that fulfill(s) a role. This role could be fulfilled by either (strictly) one Bar xor any number of Baz. Similarly, the role might be fulfilled by either any number or Bar xor any number of Baz (but a mixed collection is intolerable). Are there reasonable ways to represent these in a class diagram using only associations, classes, and interfaces? I would (really) like to avoid using OCL or constraint elements.
(The reason I would like to avoid these is because we are generating code from our UML. We have already implemented generation that handles associations, classes, and interfaces. Dealing with OCL would be quite the task. Constraint elements wouldn't be so bad but still quite a lot of work.)
I would start with the picture below and create several different versions before deciding which one generates best code (junior-40).
The yellow blocks represent necessary "glue code" needed to straighten your example against your other requirements
Consider creating an abstract class Thing and derive Bar and Baz from it. It abstract the whole role, can contain some own atts and methods if needed and is quite flexible and extendible.
Now Account has an association only with AccountOwner (role "role", as Jim L. has explained in his comment, a role name must be unique in this context).
Note that this does not eliminate the need of some additional restrictions. For example, all linked "roles" should be of the same type. Sometimes is not easy (or even possible) to remove all restrictions. Otherwise we would make complete systems out of class diagram. I agree though, that as much information as possible should be contained in classes, their taxonomies and features (atts, assocs and methods).
EXAMPLE:
EXAMPLE 2 (after comments):
This version overcomes the need to use OCL ant yet keeps the simplicity and flexibility:
Multiplicities are now also derived and refined for each concrete "role". No OCL needed. :)
You add a constraint on the class in OCL:
(self.role->exists(r|r.oclIsType(Bar)) and self.role->notexists(r|r.oclIsType(Baz)) ) or
(self.role->exists(r|r.oclIsType(Baz)) and self.role->notexists(r|r.oclIsType(Bar)))
You can try this out with MDriven Designer.
The reason for introducing OCL (object constraint language) in the UML specification was just this; ability to add constraint not possible or practical to convey with simple cardinality and type information
Could this image help you ? It is extracted from the norm.
Are you thinking of something like the following:
(source: uml-diagrams.org)
Where Account is your Foo, Person is your Bar, and Corporation is your Baz.
You can then specify multiplicity on each of the two associations: [1] for Bar (Person) and [1..*] for Baz (Corporation).
This my UML class diagram (URL)
In above diagram, ChildParent (or Child1, Child2, and Child3) can only be initialized in MainObject->create_new_object() and store it in class Library through ObjectData->lib->add_object(key, newObject).
So, how to define UML class relationship between ChildParent, Library, and MainObject?
Thank you
Relationships between classes are structural, not behavioral. The MainObject is creating it, but it is not controlling its lifespan nor does it own it in any way. After creating is it handed over to the ObjectData, transported to the Library and stored there. There is a behavioral relationship between the MainObject and the ChildParent object, but there is not a structural relationship between the two of them. I should not depict any relationship between them.
The Library is storing it. This is a typical whole part relationship and structural. What is a library without books? Therefor would I make use of the aggregation type of relation. It is not the composition, because the Library does not control the lifespan of any ChildParent or Child object nor does it imply that the ChildObject will be destroyed when the Library object is destroyed. That might happen, but given the presented data is that not clear to me.
EDIT as a reply to a comment:
Class diagrams show the structural relationships between classes, not their usage. When a class implements an interface, then will you see that relationship in the diagram. In the code (the behaviour) might you not see this relationship, because the implementation is hidden in a factory method or provided by a IoC container or it might even be a relationship that is never used.
What is the relationship between a class (the caller) that is picking a class (the callee) from a library and between the caller and the library?
It is obvious that the caller and the library have a behavioral relationship. If the module changes, can the caller get his callee from some other class. Therefor will the library and the caller have no relationship in the class diagram.
There is a structural relationship between the caller and the callee. The caller needs the callee. Your comment does not specify the exact relationship between them, but there is a relationship. The weakest form is the dependency relationship. An example in connection with a library is that a person is lending a book from a library. When he starts to read the book, is the callee used. It does not belong intrinsically to the person as a whole, but it does belong to a certain method of the person class.
There are a lot of ways to implement a library. It can be for instance a wardrobe. What is the relationship between a person in the military and his uniforms? He needs to wear some uniforms in certain situations, yet in other situations are those uniforms forbidden to wear. Wearing an uniform is a part of the class military. You can not be in the military without wearing an uniform in the time of duty. The moment you are out of the military are you not allowed to wear the uniform anymore. Hence has a military a compositional relationship with that uniform from his wardrobe.
There are more types of relationships possible between the caller and the callee. You can not say it at forehand. You must answer it the same way as any other relationship. The first question is very clear: is this a structural relationship or not? Keywords like 'is a' and 'has a' depict a structural relationship. Keywords like 'uses', 'asks', 'picks from' show a behavioral relationship. Have you concluded that it is a structural relationship, then should you find out what the dependency between the two classes is.
I am attempting to understand how I should use the realization of interfaces and the implementation of abstract classes in UML. I came across the post at https://stackoverflow.com/a/13438187/700543 whereby the poster states that pure virtual methods are interfaces whilst those that are part pure virtual methods are abstract classes. Is anyone able to give me a real world scenario and not one based on code?
An Interface is only a "class skeleton" for library users to extend, and as you said, methods cannot be implemented. An Abstract class can have implemented methods. I will give you a real life example:
Imagine I provide an Interface for people to implement sorting functions and I also provide a Class for bench marking sorting functions. My bench marking class only needs to know what methods of the Interface it needs to call in order to perform the bench marking, it does not know how they are implemented. Therefore, inside the bench marking class you might only see something like sortInterfaceInstace.getNumberOfSwap(), whereas sortInterfaceInstance is only known to be of sortInterface type at compile time, and not of any specific user sort implementation.
If you need implemented methods, use abstract instead of interfaces.
An interface only describes how something can be used, it provides none of the underlying implementation of how it gets done, i.e. a class with only pure virtual functions. An English analogy for an interface may be an adjective.
One example of an interface is a Movable interface. This interface may provide one pure virtual function move which tells the object to move to a given location. However, how it moves there is not implemented.
An abstract class on the other hand differs from an interface in that it provides some of the implementation details, but not all of them. These are conceptually high-level items that can be manipulated in certain ways, but when you get down to it the high-level item doesn't really exists or make sense by itself.
For example, say we have an abstract Shape class. The shape can have a certain origin which can be tracked independent of what Shape it is. The functions to transform the shape can be declared and implemented in the Shape class, saving the hassle of having to provide the same implementation in each sub-class. However, when you try to get the area or perimeter of the shape it's difficult to answer this without knowing more about the shape.
I have a top class, lets call it Car. I have an interface, lets call it ITyre and then I have two classes which implement ITyre. Lets call them Goodyear and Bridgestone.
Am I allowed to have a composition association between the interface ITyre and Car (from UML perspective, not a particular language)?
If you meant,
public class Car
{
ITyre something;
}
Yes, you can. In fact it will be good if you do it this way. So that your Car is not depending on any one particular concrete implementation. Your implementation here will give you flexibility to swap out tyres (DI or factory) irrespective of who built them.