Share
Explore

MADS4013 Intro to KOTLIN Feb 22 w24

Text Reference: Big Nerd Ranch Guide: Chapter 13, 14, 15
Our Course Outline for today states:
Classes
Objects
Constructors
Inheritance
Composition

We will be looking at lots of implementations of Classes and Objects.

Learning Outcomes: Kotlin Object Oriented Programming with:

Classes
Objects
Constructors

A KOTLIN Application, like any OO Language application is Community of Objects
How do we do the data plumbing to connect Objects?
Classes have 2 kinds of members:
Data Fields (attributes):
1. Scalar or Primitives
2. OBJECT of another class → this is Composition has-a
Methods

CompositionShared Field Composition
Inheritance
Method Calls



Your Simplest KOTLIN OO Program:


// Define a class called Person
class Person(val name: String, val age: Int) {
// Define a method called speak
fun speak() {
println("Hello, my name is $name and I am $age years old.")
}
}

fun main() {
// Create an instance of the Person class
val person = Person("John", 25)
// Call the speak method on the person instance
person.speak()
}




## Lab Workbook: Object-Oriented Kotlin

**Objective:** Understand the fundamentals of object-oriented programming (OOP) and how Kotlin supports OOP concepts.
In this lab workbook, you will explore essential concepts of object-oriented programming using the Kotlin programming language. The topics covered include:
- classes: are templates → Purpose of a class is to model real world entities
2 kinds of entities:
Tangible
Intangible entities :
What is a calendar entry? A relationship between people, an event, a location, datetime
objects - are instatiations of Classes
encapsulation : walled garden: visiblity on data fields: → ONLY METHODS in that class can read or mutable that variable.
Tracing method calls is some we have good tool support for (Object Interaction Diagrams)
constructors: Special Functions which are run when you construct and OBJECT: we can pre-set data fields in objects upon instantiation.
Building Communities of objects:
method calls between objects with method parameters (variables we are sending to the Called Object) - method can have a return value/ passing and return values
object composition: has-a relationships
inheritance: is-a relationships


Lab 1: Classes and Objects

**Objective:** Learn about classes, objects, and how to create them in Kotlin.
1. **Understanding Classes and Objects** - Definition of classes and objects in object-oriented programming. - The role of classes as blueprints for creating objects.
2. **Creating Objects in Kotlin** - Instantiating objects from classes in Kotlin. - Accessing object properties and methods.

Lab 2: Encapsulation and Private Data Fields: Building the Walled Garden

**Objective:** Understand the concept of encapsulation, private data fields, and the use of getter and setter methods for protecting state.
1. **Encapsulation and Walled Garden Metaphor** - Explanation of encapsulation and its role in protecting the internal state of objects. - Introducing the metaphor of a walled garden to illustrate encapsulation.
2. **Private Data Fields with Getter and Setter Methods** - Defining private data fields within a class. - Creating getter and setter methods to access and modify private data fields.

Lab 3: Constructors and Object Initialization

**Objective:** Learn about constructors and their role in initializing objects.
1. **Introduction to Constructors** - Explanation of constructors and their importance in object initialization. - Different types of constructors in Kotlin.
2. **Using Constructors** - Creating objects using different types of constructors. - Understanding how constructors initialize object properties.

Lab 4: Method Calls, Data Passing, and Return Values

Objective: Explore connecting objects through method calls, passing data, and returning values.
1. **Connecting Objects with Method Calls** - Invoking methods on objects to perform actions and operations. - Passing data as method parameters and receiving return values.
2. **Object Composition** - Understanding how objects can be composed of other objects. - Demonstrating the relationship between objects through composition.

Lab 5: Inheritance

Objective: Understand the concept of inheritance and its role in object-oriented programming.
1. **Introduction to Inheritance** - Explanation of inheritance and its benefits in code reusability. - Creating a class hierarchy with superclass and subclasses.
2. **Implementing Inheritance in Kotlin** - Extending classes to create subclasses. - Overriding methods in subclasses to provide specialized behavior.
To get a vision of how to use Inheritance:
One of the core OO principles is ABSTRACTION.

Note:

Field Composition models “has a” relationships. A car has a radio.
Inheritance models “is a” relationships. A Tiger is a Feline.



Lab 1: Understanding Classes and Objects

In object-oriented programming, classes and objects play a fundamental role in structuring a software program into reusable pieces of code. Let's explore the definition of classes and objects and their significance as blueprints for creating objects through several progressive examples.
Definition of Classes and Objects
In object-oriented programming (OOP), a class serves as an abstract blueprint for creating more specific, concrete objects.
Classes and Objects model real world tangible and intangible entities. The power of OO programming is that we can model relationships with Inheritance and Composition - these are the 2 key fundemental ways to create data plumbing between objects to create Applications - which are Communities of Objects.
Just like an architect's blueprint for building a house defines the structure, layout, and shape of the house, a class defines the structure and behavior of an object. It acts as a recipe for creating objects, specifying the properties the object will have and what it can do. Classes allow you to create objects that behave in a consistent and predictable way.
Role of Classes as Blueprints
Classes define the attributes and methods of objects. Attributes represent what the class looks like, while methods represent what the class does. When you create an object from a class, you are essentially creating an instance of that class with its own set of attributes and methods.
Classes and objects in object-oriented programming (OOP) serve as powerful tools for modeling real-world entities, both tangible and intangible. With OOP, we can create software applications that mimic the relationships and interactions between these entities, resulting in a more intuitive and efficient development process. Two key fundamental concepts in OOP that enable us to model these relationships are inheritance and composition.
Inheritance allows us to establish a hierarchical relationship between classes, where a subclass inherits properties and behaviors from a superclass. This allows us to reuse and extend existing code by creating specialized classes that inherit common characteristics from a more general class. Inheritance models the "is-a" relationship, where a subclass is a more specific type of the superclass. For example, in a banking application, we can have a general class called "Account" as the superclass, and more specific classes like "SavingsAccount" and "CheckingAccount" as subclasses, inheriting properties and methods from the "Account" class.
Composition, on the other hand, allows us to create complex objects by combining simpler objects or components. With composition, we can build more intricate systems by assembling objects to create new functionality. Composition models the "has-a" relationship, where an object contains other objects as its parts or components. For example, in a car rental system, we can have a "Car" class and a "Customer" class. The "Customer" class can have a composition relationship with the "Car" class, where each customer can have one or more cars associated with their account.
By leveraging inheritance and composition, we can create data plumbing between objects, enabling the development of robust and scalable applications. These applications can be seen as communities of objects, where each object plays a specific role and interacts with other objects to achieve a common goal. This approach allows us to model complex real-world scenarios effectively, resulting in software that is more maintainable, extensible, and closely aligned with the real-world domain.

Let's now continue with the detailed outline for each lab, starting with constructors and object initialization.

Example 1: Creating a Simple Class

// Define a simple class called Car
class Car {
// Properties
var color: String = "Red"
var model: String = "XYZ"

// Method
fun startEngine() {
println("Engine started")
}
}

fun main() {
// Create an instance of the Car class
val myCar = Car()

// Accessing object properties
println("My car's color is ${myCar.color}")
println("My car's model is ${myCar.model}")

// Calling a method on the object
myCar.startEngine()
}


Example 2: Using Class as a Blueprint

// Define a class called Dog
class Dog {
// Properties
var breed: String = "Labrador"
var age: Int = 3

// Method
fun bark() {
println("Woof! Woof!")
}
}

fun main() {
// Create an instance of the Dog class
val myDog = Dog()

// Accessing object properties
println("My dog's breed is ${myDog.breed}")
println("My dog's age is ${myDog.age}")

// Calling a method on the object
myDog.bark()
}


These examples demonstrate the creation of classes and the instantiation of objects in Kotlin. They serve as a starting point for understanding the role of classes as blueprints for creating objects.

Lab 2: Encapsulation and Private Data Fields: Building the Walled Garden

Example: Encapsulation and Private Data Fields
// Define a class using encapsulation to protect internal state
class Person {
// Private data fields
private var name: String = "John"
private var age: Int = 30

// Getter methods to access private data fields
fun getName(): String {
return name
}

fun getAge(): Int {
return age
}

// Setter methods to modify private data fields
fun setName(newName: String) {
name = newName
}

fun setAge(newAge: Int) {
if (newAge > 0) {
age = newAge
}
}
}

fun main() {
// Create an instance of the Person class
val person = Person()

// Accessing private data fields using getter methods
println("Person's name: ${person.getName()}")
println("Person's age: ${person.getAge()}")

// Modifying private data fields using setter methods
person.setName("Alice")
person.setAge(25)

// Display the updated information
println("Updated name: ${person.getName()}")
println("Updated age: ${person.getAge()}")
}

image.png
Next, we will proceed to detail the concept of encapsulation and private data fields with getter and setter methods to protect state integrity and enforce encapsulation.
// Define a class using encapsulation with a constructor
class BankAccount(private var accountNumber: String, private var balance: Double) {
// Getter methods
fun getAccountNumber(): String {
return accountNumber
}

fun getBalance(): Double {
return balance
}

// Setter method to deposit funds
fun deposit(amount: Double) {
if (amount > 0) {
balance += amount
println("Deposit of $amount successful. New balance: $balance")
}
}

// Setter method to withdraw funds
fun withdraw(amount: Double) {
if (amount > 0 && amount <= balance) {
balance -= amount
println("Withdrawal of $amount successful. New balance: $balance")
} else {
println("Insufficient funds for withdrawal")
}
}
}

fun main() {
// Create a BankAccount object using the constructor
val account = BankAccount("123456789", 1000.0)
Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.