Hierarchical multilevel inheritance

Hierarchical multilevel inheritance is where a parent class is derived from more than one class and one of the child classes is derived from another class. Take a look at the following diagram, where A is a parent class of D, and D is a parent class of E:

A classic example of this type of inheritance is the Shape class. Different shapes make up our everyday surroundings. All shapes are unique because of their structures. Some shapes, such as a circle and a cylinder, are quite similar, but other shapes, such as a square, an oval, and a triangle, are shapes that are completely different from each other. In this example, we are implementing the following shapes that are derived from the Shape class:

  • Rectangle
  • Triangle
  • Circle
  • Cylinder

The general characteristics of the Shape class are as follows:

  • Each shape has a name
  • Each shape can be drawn
  • The area of the shape can be calculated

Let's create Shape class hierarchy:

  1. Create a superclass, Shape, that has one property, name, and two functions, draw and getArea. Keep the function body empty because shape is very generic concept and we do not know which shape will be implemented. When the concept is generic, it is always a good idea to make the superclass abstract. This will be discussed in more detail in the Abstract classes section:
open class Shape(val sName: String) {
init {
println("$sName is drawn ")
}
open fun draw() {}
open fun getArea() = 0.0
}
  1. Create a class called Rectangle and extend it from the Shape class. The rectangle class has two properties, height and width, two overridden functions, getArea and draw, and one function, getPerimeter:
  • To get the area of rectanglearea = height * width
  • To find the perimeter of the rectangleperimeter = (height * 2) + (width * 2)

The perimeter of a rectangle is the length of the distance around the edge of rectangle. Override the getArea function to calculate the area, implement the getPerimeter function to calculate the perimeter, and override the draw function to display the calculated area: 

class Rectangle(_width : Double, _height : Double, _sName: String) : Shape(_sName) {

var width = _width
var height = _height

override fun getArea() = width * height

private fun getPerimeter() = (width * 2) + (height * 2)

override fun draw() {
println("Area of $sName is ${getArea()} and perimeter is ${getPerimeter()}")
}
}
  1. Create another class called Triangle and extend it with the Shape superclass. The simplest form of the Triangle class contains two properties, base and height, and two overridden functions from the super class.

To calculate the area of the trianglearea =  (base *  height) / 2:

class Triangle(_base : Double, _height: Double, _sName: String) : Shape(_sName) {
var base = _base
var height = _height

override fun getArea() = (base * height)/2
override fun draw() {
println("Area of the triangle is ${getArea()}.")
}
}
  1. Create a class called Circle and extend it from the Shape class. The Circle class contains two properties, pi and radius. To calculate the circumference of the circle, use the following formula:

Area of circle = PI * radius * radius

The distance from the center of a circle to any point on its circumference is called its radius:

open class Circle (_radius : Double, _sName: String) : Shape(_sName) {

val PI = 3.1415
var radius = _radius

override fun getArea() = PI * radius * radius
override fun draw() {
println("Area of the circle is ${getArea()}.")
}
}

Let's have a look at the class diagram:

The cylinder class is the most powerful class in the hierarchy because it receives all properties and functions from its immediate parent class, Circle, and from its parent class, Shape, as well. The cylinder class has one property, height, and one overridden function, draw. We can carry out three different calculations on a cylinder:

  • To calculate the area of the circle of the cylinderCircle = PI * radius * radius
  • To calculate the volume of the cylinderVolume = height * PI * radius * radius
  • To calculate the area of the cylinder: area = (2 * PI * radius * radius) + (2 * PI * radius * height)

The getArea() function of the Circle class provides the circumference of the circle. All other functions and properties are also derived from the circle class:

class Cylinder(_radius : Double, _height: Double,_sName: String) : Circle(_radius, _sName) {

var height = _height
override fun draw() {

var circle = getArea()
println("Circle of cylinder is $circle")

var volume = circle * height
println("Volume of cylinder is $volume")

var area = (2 * circle) + (2 * PI * radius * height)
println("Area of cylinder is $area") }
}

We can now execute the complete program. The following code creates different types of shapes and each shape takes advantage of inheritance. The circle class, for example, reuses the code from the shape class, while the cylinder class makes use of the circle class:

fun main(args: Array<String>) {

var rectangle = Rectangle(_width = 5.0, _height = 5.0, _sName = "Rectangle")
rectangle.draw()

println()
var triangle = Triangle(_base = 6.0, _height = 5.0, _sName = "Triangle")
triangle.draw()

println()
var circle = Circle(_radius = 2.5, _sName = "Circle")
circle.draw()

println()
var cylinder = Cylinder(_radius = 2.5, _height = 4.0, _sName = "Cylinder")
cylinder.draw()
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.163.13