This article mainly focuses on how OOP theory can be applied on Android using Google’s latest language, Kotlin!
The 4 main concepts in OOP are Inheritance, Abstraction, Polymorphism and Encapsulation, The most fundamental reasoning behind using OOP concepts in projects is to allow developers to scale, test, and manage their projects efficiently.
Inheritance
All classes in your project that have no defined superclass inherit from a common superclass called any in Kotlin. To make a class inheritable, you have to use the keyword open because by default a class is final and cannot be inheritable. In the simple example below, we have a class parent that has an inheritable function called eyeColor, and we have a child class that is able to access that function.
open class Favourite {
fun favColor(colorName:String) =
println("My child's eye color is $colorName")
}==========================================================
//to inherit a class you type colon(:) and the name of parent class
class Color : Favourite (){
init {
eyeColor("Blue")
}
}
Abstraction
This class holds the definitions of functions needed by all the subclasses that are inheriting from it, abstract classes do not need to know the implementations, you can make a class abstract by using the keyword abstract, abstract classes cannot be instantiated (objects cannot be created).
fun main() {
val circle = Circle(5.0)
circle.shapeName("Circle") val triangle = Triangle(2.0,3.0,4.0)
triangle.shapeName("Triangle")
}
===================================================================
abstract class Shape{
abstract fun area() : Double
abstract fun perimeter() : Double
fun shapeName(name:String){
println("The name of shape is $name")
}
}
===================================================================
class Circle (var radius : Double): Shape(){
private val pi = 3.14
init {
println("The area of circle is ${area()}")
println("The perimeter of circle is ${perimeter()}")
}
override fun area() = radius * radius * pi
override fun perimeter() = 2 * radius * pi
}
===================================================================
class Triangle (var a : Double, var b : Double,var c : Double): Shape (){
init {
println("The area of Triangle is ${area()}")
println("The perimeter of perimeter is ${perimeter()}")
}
override fun area(): Double = sqrt((perimeter() / 2) * (perimeter() / 2 - a) * (perimeter() / 2 - b) * (perimeter() / 2 - c))
override fun perimeter() = a + b + c
}
In the code above , circle and triangle class is instantiated in the main class and a name is passed as a parameter and inside the init block of these classes the methods is where the logic/implementation is handled. The shape class only has the definitions of the methods needed by any classes that inherits it.
Encapsulations
is a term used to describe the scope visibility of variables and functions in classes, there are 4 main types of visibility modifiers
Public , by default all classes and variables are public , which means they are accessible for the entire project.
Private, variables and functions which are private can be accessed only within the class they are declared in.
Protected , these variables and functions can be accessed within the class and all classes which inherit this class
Internal, internal allows visibility in the same module.
Polymorphism
Which means “occurring in several different forms”, can be demonstrated by overriding and overloading functions or variables.
Overriding the process of re-declaring existing variables or functions in superclass for different implementations. to override a particular variable or function it must be declared using the open keyword in the superclass and then the keyword override should be used in the child class which overrides it.
open class Car {
open val speed:String = "Average speed 200Kmph"}==========================================================class Bmw : Car (){
//you can override a val with var but not vice versa
override val speed = "Bmw speed 250Kmph"
}
overloading is done when you want create functions with similar functionality and name but also want the compiler to be able to distinguish each functions uniquely,you can overload a function by have different parameter types or different amount of parameters, overloading can also be seen through out your kotlin projects example such as the inbuilt println() function which can take any parameter.
fun main() {
println("This is 1st methods max 1 : ${getMax(2, 3)}")
println("This is 1st methods max 3 : ${getMax(6.4, 3)}")
println("This is 1st methods max 2 : ${getMax(2.4, 3.4)}")
println("This is 1st methods max 4: ${getMax(4, 3 , "4th get max")}")
}
//1
fun getMax(a: Int, b: Int) = if (a > b) a else b
//2
fun getMax(a: Double, b: Double) = if (a > b) a else b
//3
fun getMax(a: Double, b: Int) = if (a > b) a else b
//4
fun getMax(a: Int, b: Int, c:String) = if (a > b) a else c
This article was an overview of these basic concepts in kotlin , you can check out the kotlin documentation for more information :