Bob Senegal wrote:
just looked through this post and I think it's an interesting question ..
imaging that you have an Interface and you add a port to it ...
can another class inherit from it from that interface ... so that it will be also inheriting the ports from that interfacse .... is this supported by UML2.1 ? ... is this possible with Rhapsody ?
The two questions are:
1. Is this possible with Rhapsody
2. Is this valid UML 2.1
I will try to answer both of these, starting with question number #1 first: is this possible with Rhapsody?
As it turns out, in a recent project I tried to create an Interface with a Port attached to it. The goal was to have the classes that realized this Interface also "inherit" the Port. The reasoning behind this was not quite straight forward and I will try to explain it below, but the short answer is that Rhapsody in C does not generate code correctly for this. I contacted tech support and was told that this does work in Rhapsody in C++. They filed a Defect on my behalf.
I admit that attaching a Port to an Interface is a strange concept and I will now try to explain why I even tried it in the first place.
What I really wanted to do was use a Port so that two classes can communicate across it without either class explicitly knowing who or what is attached to the other side of the Port. A pretty typical use for Ports. However, there is a pretty sever limitation in Rhapsody in C:
Rhapsody in C can only generate code for Ports with events, not events and functions.
For my application, I wanted to be able to make function calls and send events across the Port. Unfortunately, this was impossible. Further more, the only form of inheritance that is supported in Rhapsody in C is through realizing an Interface. However, an Interface can only contain function calls (not events). Simple enough, I thought, and tried adding a Port to the Interface so that each class that realized the Interface would contain the same Port. The code that was generated did not compile. However, it only took a simple tweak to the generated code to get things working. It looked like a name mangling bug in the code-generator, nothing else.
I sent tech support an email and was told that it works in C++, and therefore he believed it was a defect in Rhapsody in C. I didn't think much of it until I saw this post here. In fact, based on the timing of my tech support email and this post - I had a suspicion that raddy may have been my tech support contact . :) If anyone is interested in the final work-around I adopted let me know - maybe I'll create a new post as this one is getting too long already.
After seeing this post I was prompted to research the answer to question #2: is this valid UML 2.1?
Based on my current understanding of the UML superstructure document I believe the answer is NO. However, I am continually confused while reading said document and wish it was as easy to read as the ISO C standard.
Here is my reasoning. (All quotes and references are to UML Superstructure document version 2.1.2)
Section 9.3.1 defines Class. If we look the the hierarchy of Class we can see it looks like this:
Classifier <- StructuredClassifier <- EncapsulatedClassifier <- Class
Likewise, the hierarchy of Interface (7.3.24) is:
Classifier <- Interface
Note that Interface bypasses EncapsulatedClassifer and StructuredClassifer.
Interface has the following Associations:
- ownedAttribute: Property
References all the properties owned by the Interface. (Subsets Namespace::ownedMember and Classifier::feature)
- ownedOperation: Operation
References all the operations owned by the Interface. (Subsets Namespace::ownedMember and Classifier::feature)
- nestedClassifier: Classifier
(References all the Classifiers owned by the Interface. (Subsets Namespace::ownedMember)
- redefinedInterface: Interface
(References all the Interfaces redefined by this Interface. (Subsets Element::redefinedElement)
So it is clear that an Interface can have attributes and operations. But no mention of Ports.
Furthermore, if we look at EncapsulatedClassifer (9.3.8), we see that its description is:
Extends a classifier with the ability to own ports as specific and type checked interaction points.
and has the new Association:
/ownedPort: Port [0..*]
The set of port attributes owned by EncapsulatedClassifier. (Subsets Class::ownedAttribute)
OK, even more proof that a Class can own a Port (because it inherits from EncapsulatedClassifier).
This seems pretty good. But I still have some questions. This goes back to my statement about not always understanding the Superstructure document.
Question 1:
If we look at Classifier, which Interface inherits, there is one attribute that stands out:
/attribute: Property
If we look at Port (section 9.3.11) we see that it inherits from Property. Strange. So why can't a Port just be an attribute of Classifier? and therefore an attribute of Interface? What is so special about EncapsulatedClassifier that it magically allows classifiers to own Ports?
Question 2:
If we look at the definition of EncapsulatedClassifer (9.3.8) we see that the Association /ownedPort, is derived (the / in front of it) and that it subsets Class::ownedAttribute. I don't see how EncapsulatedClassifier subsets something in Class when EncapsulatedClassifer has no inheritance path through Class?