Enterprise Architect & UML: subtleties when choosing interface or abstract class - interface

I am currently building a model from existing C++ code. There is a (dynamically loadable) library that must therefore implement/provide a defined interface (class). The class which is used has some pure virtual functions, but it is - admittedly - not a pure interface (in the Java sense) as it is also a base class containing state (members) and a few method implementations.
So it is kind of a hybrid - base class in C++ reality, but an interface in its main purpose.
Note: I do not intent to generate some code, but the model should be correct for documentation purposes.
When drawing an example in EA (12), some questions arise:
a) are there any important reasons to prefer a class and make it 'abstract' (gray box "Base"), or should I directly use an Interface from the toolbox (purple box "Base2")? So far I could not notice any behavioral difference in EA except the color.
b) How can I suppress the stereotype {abstract} written behind the methods? When I do not set them to "abstract", they are not drawn in italic letters. But I want them italic, without the "{abstract}".
c) Similar question concerning the class/interface boxes: aren't interfaces abstract by definition? So why does EA add the {abstract} text here? It was sufficient to draw the class name italic.
d) I guess that the most left arrow (generalization of a base class) and the most right arrow (realization of an interface) are correct, and the middle one is not. Right?

a) Take either, but be consistent. The difference is a bit esoteric and except for rare cases not worth while (YMMV).
b) It looks like you filled Context/Advanced/Multiplicity with the value abstract
c) Yes. Interfaces are abstract and if you look at the Details tab you'll see that the Abstract box is ticked and can't be changed. I have no idea where that curly bracketed text comes from. It's not a stereotype. The only way I could show it like that was to change the type from int to int {abstract}.
d) You can well implement more than one interface in a class so theoretically all connectors are fine. So Derived implements two interfaces.
Edit As #minastros found out himself (and PMed me) the culprit was one of the zillion flags in the EA options:

As Thomas mentions, an interface is an abstract class technically, although an abstract class isn't always an interface. If you have even one operation (method) that isn't implemented, the class is abstract, so it follows that if none of the operations are implemented, the class is also abstract. An "abstract class" is often only thought of as a class with partial implementation since such an abstract class is different from an interface. However, a class with no implementation--an interface--technically is also an abstract class.
That's probably why EA puts the {abstract} attribute on an interface (it isn't a stereotype in the diagram, it's an attribute--stereotypes use <>). I wouldn't do it myself, since it goes without saying.

Related

Dart: What is the difference between implements and extends in Dart

https://dart.dev/guides/language/language-tour#implicit-interfaces
I've seen code that uses "implements", so I'm looking into "implements".
But I can't really tell the difference from extends by looking at the official docs.
Looking at the sample code in the official documentation (page above), it looks like it is just doing what it can do with extends with implements.
Then I wonder if it should use "extends".
I think I've understood about inheritance (extends) and mixins (with) so far.
The word "interface" is also mentioned in the Dart documentation, but there is a clear definition of "interface".
I can't even find where it is.
I don't have much knowledge about interfaces in other languages, so it's hard to get an image.
What exactly is the difference between inheritance and implementation?
Because of the difference, when do you use the inheritance "extends" and when do you use the implementation "implements"?
Is there somewhere in the sample that makes a clear difference?
Given class MyClass:
MyClass extends Foo is classic inheritance. MyClass is a Foo
MyClass implements Bar is declaring that the implementer conforms to the Bar interface. MyClass "looks" like a Bar
MyClass with Batz is "mixing" in the interface and implementation. MyClass "acts" like a Batz.
MyClass can implement and mixin as many interfaces as needed (some limitations apply) but can only extend from one interface.
Besides other explanations, dart does not let developers to use multiple inheritance so there can be only one extends, however there can be more than one implements.
Therefore a class can be subtype of only one class(except parents of parent class) but interfaces defines behaviour of the class which implements it and one class can have different behaviours.
A simple analogy is from animals. If we assume there is different behaviours for animals like swimming interface as ISwimmer, running interface as IRunner and flying interface as IFlyer. For example a Fish class is an Animal. Which makes it extends Animal class. Additionally a Fish has behaviour of swimming so it implements ISwimmer interface in that purpose.
If you just want to understand how they are different concept-wise then,
You extend a class. Think of it as you extended your father or your father is your base class.
You implement an interface(which is just a purely abstract class). Like Ferrari implements a car.
An interface cannot have an instance. For example - Have you seen any CAR? The answer is no, you have seen types of car i.e, Ford, Toyota which implements the CAR so the car acts as an interface which other companies or you can say, classes(Ferrari) implements.
You have to implement every feature of a car to be called a car that's why every method of an interface needs to be implemented and we say x "implements" y.
In extending you can override something and skip another , suppose your nose may look like your father but your ears do not.
Think of an interface as a skeleton or just an empty class.

Is it better to implement two classes or one class in the following case?

I have a class "Vertex" with 4 attributes and a class "Vertex_" with one attribute. The one attribute in Vertex_ is also in Vertex. Is it a good design to keep the two classes or is it better to program just the class Vertex, although there will be 3 variables, which are not used, when I instantiate an object which needs just the one attribute?
Class Vertex_ is actually somewhat a duplicate of Class Vertex.
I would suggest using inheritance and having Class Vertex inherit the attribute from the parent Class Vertex_ while having the 3 other attributes Class Vertex_ does not have.
TL;DR
This is a question that deserves a very long answer.There are two reasons for inheritance and the reason for doing it can depend on the language being used. One reason is for code reuse. Without knowing anything else about your situation, it would seem you are inheriting simply to reuse an attribute (but I suspect there could be more you will be reusing). But, there are other ways of getting code reuse without inheritance, for example containment, which is often a better way.
A powerful feature of object-oriented programming is the ability to substitute one type of object for another. When a message is sent to that object, the correct method implementation is invoked according the actual type of object receiving the message. This is one type of polymorphism. But in some languages the ability to substitute one object for another is constrained. In Java I can only substitute an instance of class B for an instance of class A if B is a descendant of A. So inheritance becomes important in Java to support polymorphism.
But what does it mean to be able to substitute a B instance for an A instance? Will it work? Class A has established a contract stating what each of its methods requires before you can successfully call it and at the same time states what each method promises to deliver. Will the methods of class B live up to that contract? If not, you really cannot substitute a B for an A and expect the program to run correctly. B may be a subclass of A but it is not a subtype of A (see Liskov substitution principle]).
In a language such as Python, inheritance is not required for polymorphism and coders are more apt to use it as code-reuse mechanism. Nevertheless, some people feel that subclassing should only be used to express subtyping. So, if Vertex_ is only using one of the four attributes it has inherited, I am doubtful that an instance of Vertex_ could be safely substituted for an instance of Vertex. I would not do the inheritance unless the language were C++ and then I would use private inheritance.

How to implement class relationship between two classes where one class can perform all functions of another class but actually is not a subclass?

I'm creating a student information system which will have two access levels namely admin and manager. The Admin class can perform all functions of Manager class along with some additional functions. But literally speaking an Admin is not a manager. So how should I implement this relationship? Is it okay to do Admin extends Manager or is there any other way to implement this? (I'll be using java to implement the system)
Well, UML provides 3 mechanisms to depict (some) similarity between classes.
Generalization
Interfaces
Substitution
Let's look at them closer:
Generalization
When two classes are in generalization relationship, one of them (subclass, specialized or child class) is a kind of the other (superclass, general or parent class). Child class has all attributes and methods of its parents (inherits them) and can have some additional attributes or methods and can handle some methods in a different matter.
Generalization is depicted with a solid line and an arrow whose head is an empty triangle. Head is pointing the more general class
Interfaces
Actually interfaces are not a direct relationship between two classes that are in some way similar. But they help to show it to some degree.
Interface is a specific kind of a class that has a collection of methods. Interface is not directly instantiated, but other classes can either realize the interface or require an interface.
If a class realizes an interface (or provides it in other words) then it has to have all the methods of an interface, however interface in no way enforces a method of implementation.
So we may have two (or more) classes that realize the same interface and then both those classes will be able to perform the same functions, however it might be a totally different way.
We show interface realization by a dashed line and an arrow in a form of empty triangle, pointing the interface.
The class that requires the interface is the class interacting with those classes providing the interface.
To show interface usage you use a dashed line with an open arrow and stereotype <<use>> (well, technically it is not a stereotype).
Substitution
Class substitution is used to shown that one class can step into the role of the other class but it is not a kind of that class. A substituting class has to have all methods of the class it substitutes but it might have different internal representation.
This relationship is used when two or more classes can perform similar roles but they are not of the same kind.
Substitution relationship is shown as a dashed line with an open arrowhead pointing the class that can be substituted and a stereotype <<substitute>>
Your case is substitution, where Admin can substitute Manager, however you can combine substitution with interfaces to make it clearer.
Also always make sure that the recipient of your documentation will understand the element models you're going to use.
Just make a parent class with the methods shared by both Admin and Manager.

How do we draw abstract method in uml class diagram

public abstract class Shape {
abstract int area();
}
How do we draw the UML class diagram for the abstract method? Use +, - or #?
public class Room {
int nWindows;
}
And what if the class instance variable doesn't have public, private or protected?
Abstract
According to UML specification:
The name of an abstract Classifier is shown in italics, where permitted by the font in use. Alternatively or in addition, an abstract Classifier may be shown using the textual annotation {abstract} after or below its name.
Note however that Operation is not a Classifier. It still has an isAbstract attribute as a BehavioralFeature but 2.5 specification does not define how to model the fact of being abstract. Older specifications (1.4.x) were using the same method as for Classifiers and it is a widely recognized method to show operation abstraction. Note only that the elements in curly brackets for features are presented at the end of line rather than just after the name (Classifier simply has no other specification directly after name).
Possibly authors made an omission in 2.5 specification for Feature abstraction notation by a mistake.
An abstract operation can of course have any visibility kind.
Of course the operation might be abstract only if its containing Classifier (Class in your case) is also abstract.
No visibility kind
In general visibility kind in UML is optional i.e. you can simply omit it. Just take into consideration that UML is a model so it actually can ignore some irrelevant elements or can specify them at a later stage of modelling. Not using any visibility kind in UML does not allow you to make any assumption about it's final visibility kind.
On the other hand if in actual code you use no visibility kind specification (if allowed at all) there is some default behaviour. For example
in Java it's package (#) - in UML understanding, Java calls it "package-private",
in C++ you'll end up with private feature (-),
in PHP such features are treated as public (+)
and so on.

When to use an abstract class with no interface?

Whenever I create an abstract class I tend to create an interface to go along with it and have other code refer to the interface and not the abstract class. Usually when I don't create an interface to start with I regret it (such as having to override all implimented methods to stub the class for unit testing or later down the line new classes don't need any of the implimentation and override everything also finding themselves unable to extend any other class).
At first I tried to distinguish when to use an interface and when to use an abstract class by considering is-a vs able-to but I still would end up suffering later down the line for not making an interface to start with.
So the question is when is it a good idea to only have an abstract class and no interface at all?
When you wish to "give" some base class functionality to derived classes but when this functionality is not sufficient to instantiate a usable class, then go for abstract classes.
When you wish that some classes completely implement a set of methods (a public contract), then it is a convenient to define such contract with interfaces and enforce them onto classes by making them inherit this interface.
In short:
With abstract classes you give some common base functionality to derived classes. No further actions are necessary unless abstract class has some stubs (which have to be implemented down there).
With interfaces you require derived classes to implement a set of functions and you do not pass along any implementation.
So the question is when is it a good idea to only have an abstract class and no interface at all?
When you do not wish to enforce any public contract (a set of methods/properties defined by an interface).
Also when you do not plan to use certain coding techniques like casting object to an interface type (run-time polymorphism) or limit allowed input (some method argument will only accept object of types which implement certain interfaces).
Well, the main case it is useful to have only an abstract class without any interface is to mark a certain type. It is useful to be able to check if an object "is-a" something. These interface "mark" an objet to be of a certain type. Depending on the language you use, different design patterns apply ...
These sort of abstract classes exist in java. You can also use them in C++ with RTTI.
my2c