- A class that cannot exist by itself. They are meant to be subclassed
- They can contains both abstract and concrete methods
- When used, can be understood as an identity ("is-a X")
- Designed to share code and state
- Prefer the interface if possible
Python can have multiple parent class (if methods override, then they are executed in the order of parent declaration)
from abc import ABC, abstractmethod
class Shape(ABC):
def __init__(self, name: str):
# An abstract class can have a constructor and state!
self.name = name
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
# A concrete method
def display_info(self):
print(f"--- {self.name} ---")
print(f"Area: {self.area():.2f}")
print(f"Perimeter: {self.perimeter():.2f}")
print()
class Rectangle(Shape):
def __init__(self, width, height):
super().__init__("Rectangle") # Calls the parent constructor
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
Java classes can only have 1 parent class (diamond problem)
abstract class Shape {
abstract double area();
abstract double perimeter();
}
class Rectangle extends Shape {
private double width;
private double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
double area() {
return width * height;
}
@Override
double perimeter() {
return 2 * (width + height);
}
}
- A class that cannot exist by itself. They are meant to be subclassed
- They can only contains abstract methods and variables
- When used, can be understood as a capability ("Can-do X")
- Class that implement interfaces are more independent : they can be what they want as long as they use the absract functions of the interface
Python do not offer proper interface class, so we use the Abstract Base Class (ABC) but without :
- A constructor
- Concrete methods
- Set variables
We could actually do that, but that would then be a classic abstract class.
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
Java classes can have multiple implemented interfaces.
interface Shape {
double area();
double perimeter();
}
class Rectangle implements Shape {
private double width;
private double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public double area() {
return this.width * this.height;
}
@Override
public double perimeter() {
return 2 * (this.width + this.height);
}
}
B
is aA
⟶B --|> A
- The class
B
have a parent classA
- See Abstract class above
classDiagram
direction LR
class Shape {
<<abstract>>
+area()
+perimeter()
}
class Rectangle
class Circle
Shape <|-- Rectangle
Shape <|-- Circle
B
do the actions specified inA
⟶B ..|> A
- The class
B
have an interface classA
- See Interface class above
classDiagram
direction LR
class Shape {
<<interface>>
+area()
+perimeter()
}
class Rectangle
class Circle
Shape <|.. Rectangle
Shape <|.. Circle
- Weak relationship
- One class just use another one for a task
- Use it when a
B
function useA
B
usesA
⟶B --|> A
classDiagram
direction LR
note "<center>Here DrawingCanvas use a Shape object <br> when drawing it <br> but the shape is not stored in DrawingCanvas</center>"
class Shape
class DrawingCanvas{
draw_shape(self, shape: Shape)
}
Shape <-- DrawingCanvas
- Weak relationship
- Only class contains another one, but they can be independant
- Use it when a
B
has aA
and ifA
is deletedB
can still exists B
has aA
⟶B --o A
classDiagram
direction LR
note "<center>Here a drawing can have <br> an empty or non empty list of Shape</center>"
class Shape
class Drawing{
List~Shape~ shape
}
Shape o-- Drawing
- Strong relationship
- One class contains another one, they cannot be independant
- Use it when a
B
has aA
and ifA
is deletedB
can still exists B
ownsA
⟶B --* A
classDiagram
direction LR
note "<center>A Polygon owns points<br>and cannot exist without them</center>"
class Polygon
class Point
Point *-- Polygon
- Tell how many class
A
can be linked withB
classDiagram
direction LR
class Polygon
class Point
Point "3..*" *-- "1" Polygon
note "<center>A Point can only be owned by 1 Polygon<br>A Polygon can owns 3 points or more</center>"