Question 1: Using Inheritance
A class which inherits from a superclass is called a subclass. The reason for using inheritance and subclasses is because some class can be broken down further (for example, an employee in a company is very general, and it is useful to have more information like what type of employee he is – manager, janitor – A basic analogy is some employees are managers).
def __init__(self, name, salary):
self._name = name
self._salary = salary
return self._salary/26 # fortnight pay
Define a new subclass of Employee called Worker. A worker has a manager, who is another employee; their manager is given as an argument to the constructor.
You should define a method get_manager that returns the worker’s manager.
boss = Employee(‘Mr. Burns’, 1000000)
worker = Worker(‘Waylon Smithers’, 2500, boss)
Define another subclass of Employee called Executive. An executive has a yearly bonus in addition to a wage. Override the Employee.wage method in order to take the bonus into account. You must call Employee.wage from Executive.wage (using super). Remember that the existing wage method calculates a fortnightly pay, but the bonus is annual.
executive = Executive(‘Joseph Bloggs’, 25000, 10000)
Tests to Satisfy:
Explanation: Since Worker and Executive classes are subclasses of Employee, they must inherit the variables of Employee class (which are name and salary). This is done by using super().__init__(name, salary). All other variables that are class-specific to Worker and Executive also have to be listed out. The wage(self) method in the Executive class is calculated by the worker’s current wage and the added bonus paid fortnightly (which is calculated by dividing the yearlyBonus of that specific worker by 26).
Question 2: Method Calls
Consider the following class definitions.
obj1 = C1()
obj2 = C2()
obj3 = C3()
obj4 = C4()
For this problem you are to consider which methods are called when the f method is called. Because the classes form part of an inheritance hierarchy, working out what happens will not always be straightforward.
For each of obj1, obj2, obj3, and obj4, print out the methods which will be called following a call to objn.f(). You should print a single line in the format: objn: call1, call2, call3.
Tests to Satisfy:
To call obj1 , we print the methods C1.f and C1.g since it is not a subclass.
To call obj2 , we call C2.f (since that class has its own method), but it must reference C1’s g method since C2 is a subclass of C1.
To call obj3, we need to call C1.f (since C3 is a sub-class of C1 and has no C3.f method). C3.g is called since C3 has the method C3.g
To call obj4 , we call C4.f (since that class has its own method). It must refer to C3’s g method because C4 is a subclass of C3.
Question 3: Polymorphism
The idea behind polymorphism is that several different types of objects can have the same methods, and be treated in the same way. For example, let’s say we defined Shape as an abstract base class. It doesn’t provide any functionality by itself, but it does supply an interface (in the form of .area() and .vertices() methods) which are meaningful for any type of 2D Shape.
Task: Write RightAngledTriangle and Rectangle subclasses of Shape
The constructor for RightAngledTriangle accepts one argument, vertices, being a list of the points of the triangle relative to its origin. The first vertex will be at the right angle.
The constructor for Rectangle accepts width and height.
Tests to Satisfy:
Explanation: Rectangle class must inherit origin from Shape, and the height and width of Rectangle class must be initialized. The area method of Rectangle class is calculated by the width multiplied by the height of an object of Rectangle class. For the vertices method, we first set x,y as a variable pair for the origin (so that it is like a coordinate system). Let’s set one of the corners of the rectangle (x,y), the next corner would be (x, y + self._height) (bottom left corner), the next corner would be (x + self._width, y + self._height) (bottom right corner) and the last corner would be (x + self._width, y) (top right corner).
For the RightAngledTriangle class, it must also inherit origins from Shape. The vertices of the RightAngledTriangle class must be initialised. To do this, we assign each vertice (input into RightAngledTriangle class) to select specific parts of that list because vertices is given as a list of coordinates. The vertices method just requires us to print the vertices variables we assigned in a list. The area method is slightly more tricky, because it requires us to look at the list of vertices. self.vertices3 is defined to be the top-most corner of the triangle, and therefore by multiplying the height with the width of the triangle and by 1/2, we get the area of the right-angled triangle. Remember that the coordinates are also considered a list, so we can specifically extract the x-value and y-value.