# The Essential Guide to Object-Oriented Programming in Kotlin

## Introduction

In the [previous article](https://hardiksachan.hashnode.dev/getting-started-with-kotlin), we learned the foundations of object-oriented programming with Kotlin. We set up our development environment, installed Android Studio and the Android SDK, and explored the basic syntax of Kotlin, including variable declarations, data types, control flow, and defining and calling functions.

Now, we're ready to take our understanding of Kotlin a step further by exploring the basics of object-oriented programming in Kotlin. This article will go over how to define and use classes and objects in Kotlin, including constructors, properties, and methods.

But, before we get into the specifics, let's define exactly what we mean by "classes" and "objects."

### What are classes and objects?

A class is a template that specifies the properties and behavior of a specific type of object. A class can have both properties (variables that store data) and methods (functions that perform actions).

An object is a class instance. When you create an object, you are essentially creating a specific instance of a class, complete with its own set of properties and methods. You can make multiple objects from the same class, each with its own set of properties and behaviors.

Classes and objects are useful for organizing and encapsulating code, as well as creating reusable components that can be reused throughout a program. They are a necessary tool for developing complex software applications.

Now that we've covered the fundamentals of classes and objects, let's look at why they are important for you as an android developer.

### Why are classes and objects important for Android development?

As an Android developer, learning how to define and use classes and objects is essential for building efficient, maintainable, and scalable Android apps. Here are a few reasons why:

* **Organization and structure:** Classes and objects enable you to break down your code into logical units that are easier to understand and work with. This can assist you in writing more organized and maintainable code, particularly as your projects grow larger and more complex.
    
* **Reusability:** You can create reusable components that can be used in different parts of your app by defining classes and objects. You will save time and effort because you will not have to rewrite the same code over and over.
    
* **Modularity:** Classes and objects allow you to divide your code into self-contained units that can be tested and debugged independently. This can help you identify and fix bugs in your code, as well as add new features and functionality.
    

Overall, understanding classes and objects is an important step toward becoming a skilled Android developer. In the sections that follow, we'll look at how to define and use classes and objects in Kotlin so that you can use them in your Android projects.

## Defining **a class in Kotlin**

In Kotlin, you can define a class by using the `class` keyword followed by the class name. For example, you could define a class called `Person` like this:

```kotlin
class Person {
    // class body
}
```

In the following sections, we'll look at how you can define the properties and methods of the class inside the class body.

You can also define a class with a primary constructor, which allows you to initialize the class with specific values when creating an object from it. We'll go over primary constructors in greater depth later in the article.

### Defining class properties

You can define the class's properties within the class body by using the `val` or `var` keyword, followed by the property name and type. For example, you could define a `String` property called `name` as follows:

```kotlin
class Person {
    val name: String
}
```

You can also provide an initial value for the property by assigning it to a default value in the constructor. For example:

```kotlin
class Person(val name: String = "") {
    // class body
}
```

The name property is declared as a `val` in this instance, making it a read-only property that cannot be modified after initialization. Use the `var` keyword in its place to define a property that can be modified:

```kotlin
class Person {
    var age: Int
}
```

Properties in Kotlin are `public` by default, which means they can be accessed and modified from anywhere within the class and from outside the class. You can, however, use visibility modifiers to control the visibility and accessibility of your properties.

Here are the four visibility modifiers in Kotlin:

* `private`: A `private` property can only be accessed and modified within the class in which it's defined.
    

```kotlin
class Person {
    private val name: String
}
```

* `protected`: A `protected` property can only be accessed and modified within the class in which it is defined and any subclasses of that class.
    

```kotlin
class Person {
    protected val name: String
}
```

* `internal`: An `internal` property can be accessed and modified from anywhere within the same module (i.e. a set of compiled Kotlin files).
    

```kotlin
class Person {
    internal val name: String
}
```

* `public`: A `public` property can be accessed and modified from anywhere within the class as well as from outside the class. This is the **default visibility** in Kotlin.
    

```kotlin
class Person {
    public val name: String
}
```

You can control who can access and modify your properties by using visibility modifiers, which can help you write more secure and maintainable code.

### Defining class methods

In addition to properties, methods can also be defined in a Kotlin class. A method is a function that executes a specific action and may or may not return a value.

In Kotlin, you define a method by using the `fun` keyword, followed by the method name, any arguments, and the return type (if applicable). For example, in the `Person` class, you could define a `greet` method that takes a `name` argument of type `String` and returns a `String`:

```kotlin
class Person {
    fun greet(name: String): String {
        return "Hello, $name!"
    }
}
```

You can also define methods that don't have any arguments or return values:

```kotlin
class Person {
    fun sayHello() {
        println("Hello!")
    }
}
```

Or you can define methods with default values for their arguments, which allows you to call the method with fewer arguments:

```kotlin
class Person {
    fun greet(name: String = "stranger"): String {
        return "Hello, $name!"
    }
}
```

Methods in Kotlin, like properties, are `public` by default, which means they can be called from anywhere within and outside the class. However, just like with properties, you can use visibility modifiers to control the visibility and accessibility of your methods.

We'll look at how to create objects from classes and use their properties and methods in the following section.

## Creating objects

Now that we've gone over how to define classes, as well as their properties and methods, let's look at how to create objects from those classes.

You can create an object from a class in Kotlin by simply calling the class name with any necessary arguments. The basic syntax is as follows:

```kotlin
val obj = Person()
```

This will create a new object from the `Person` class and assign it to the `obj` variable. You can then access the object's properties and methods using the `.` operator:

```kotlin
val obj = Person()
val name = obj.name  // access the 'name' property
obj.sayHello()       // call the 'sayHello' method
```

If the class has a primary constructor, you can pass in arguments when you create the object to initialize its properties. For example:

```kotlin
class Person(val name: String, var age: Int) {
    // class body
}

val obj = Person("Alice", 25)
```

This creates a new `Person` object with the name "Alice" and age 25.

In the next section, we'll take a closer look at primary constructors and how to define them in Kotlin.

## Constructors

### Defining a primary constructor

To define a primary constructor for a class in Kotlin, use the `constructor` keyword. A primary constructor is a type of constructor that allows you to initialize a class with specific values when creating an object from it.

The `constructor` keyword is followed by any necessary arguments and the class body to define a primary constructor. For the `Person` class, for example, you could define a primary constructor that accepts a `name` and an `age` argument:

```kotlin
class Person constructor(val name: String, var age: Int) {
    // class body
}
```

This primary constructor allows you to initialize the `name` and `age` properties of the `Person` class when you create an object from it:

```kotlin
val obj = Person("Alice", 25)
```

It's also possible to define a primary constructor with default values for its arguments, which allows you to create objects with fewer arguments:

```kotlin
class Person constructor(val name: String = "", var age: Int = 0) {
    // class body
}

val obj1 = Person()      // name = "", age = 0
val obj2 = Person("Bob") // name = "Bob", age = 0
```

In the next section, we'll take a look at how to define and use secondary constructors in Kotlin.

### Defining secondary constructors

Kotlin allows you to define secondary constructors for your classes in addition to primary constructors. A secondary constructor is defined in addition to the primary constructor and allows you to initialize the class in various ways.

The `constructor` keyword is followed by any necessary arguments and the class body to define a secondary constructor. For example, for the Person class, you could define a secondary constructor that takes a `name` argument and sets the `age` property to a default value:

```kotlin
class Person(val name: String, var age: Int) {
    constructor(name: String) : this(name, 0) {
        // constructor body
    }
}
```

This secondary constructor allows you to create a new `Person` object with just the `name` property initialized:

```kotlin
val obj = Person("Alice")
```

It's also possible to define multiple secondary constructors, each with its own set of arguments and initialization logic. For example:

```kotlin
class Person(val name: String, var age: Int) {
    constructor(name: String) : this(name, 0) {
        // constructor body
    }
    
    constructor(age: Int) : this("", age) {
        // constructor body
    }
}

val obj1 = Person("Alice") // name = "Alice", age = 0
val obj2 = Person(25)      // name = "", age = 25
```

Secondary constructors are useful when you want to provide multiple ways for your class to be initialized based on the data you have available.

In the following section, we'll look at how to use properties and methods from inside as well as outside the class.

## Using class properties and methods

Now that we've covered how to define classes, their properties, and methods, let's look at how to use them both within and outside of the class.

### Using **class properties and methods within the class**

To use a class property or method within the class, simply type `this` keyword followed by the name of the property or method. Here's an example:

```kotlin
class Person(val name: String, var age: Int) {
    fun sayHello() {
        println("Hello, my name is ${this.name} and I am ${this.age} years old.")
    }
}
```

In this example, the `sayHello` method uses the `this.name` and `this.age` properties to print a greeting.

### Using **class properties and methods from outside the class**

To use a class property or method from outside the class, you use the `.` operator followed by the property or method name. Here's an example:

```kotlin
val obj = Person("Alice", 25)
val name = obj.name  // access the 'name' property
obj.sayHello()       // call the 'sayHello' method
```

In this example, the `obj` variable is an object from the `Person` class, and the `name` and `sayHello` properties and methods are accessed using the `.` operator.

## Conclusion

We've now covered the fundamentals of Kotlin classes and objects! We've learned how to define classes, as well as their primary and secondary constructors, as well as how to create objects from those classes and use class properties and methods.

In the next article in this series, we'll delve even deeper into the world of Kotlin by looking at inheritance and polymorphism. We'll see how to use abstract classes and interfaces to define common methods and properties that can be implemented by multiple classes, as well as how to use polymorphism to allow objects to change forms at runtime.

Stay tuned for more exciting adventures in Android development with Kotlin!
