Generic Data Types
Generic Data Types
Generic types, or generics for short, allow a data type, such as a class, to
specify an unknown placeholder data type that can be used with its
properties and method.
Generic Data Type Syntax
Generic Data Types
The placeholder name can then be used wherever you use a real data type within
the class, such as for a property.
Generic Data Types
The data type that the generic type uses is passed as a parameter in angle brackets
when you instantiate the class.
Refactor your code to use generics
class Question<T>()
Refactor your code to use generics
● Add the questionText, answer, and difficulty properties. The questionText should be of
type String. The answer should be of type T because its data type is specified when
instantiating the Question class. The difficulty property should be of type String.
class Question<T>(
val answer: T,
)
Refactor your code to use generics
● .An enum class is used to create types with a limited set of possible values.
Enum Class Syntax
● .An enum class is used to create types with a limited set of possible values.
Enum Class Syntax
● Each possible value of an enum is called an enum constant. Enum constants are placed
inside the curly braces separated by commas.
● The convention is to capitalize every letter in the constant name.
● You refer to enum constants using the dot operator.
Use an enum constant
}
Use an enum constant
❖ When initializing the three questions, pass in the enum constant for the difficulty.
val question3 = Question<Int>("How many days are there between full moons?", 28,
Difficulty.HARD)
Data class
★ When a class is defined as a data class, the following methods are implemented.
★ equals()
★ hashCode()
★ toString()
★ componentN(): component1(), component2(),
va l questionText: String,
val answer: T,
)
Singleton Object
A singleton is a class that can only have a single instance. Kotlin provides a
special construct, called an object, that can be used to make a singleton class.
Singleton Object Example
Tracking of the total number of questions with ten questions and three
answered questions.
object StudentProgress {
}
Accessing Singleton Object
fun main () {
}
Companion objects
A companion object allows you to access its properties and methods from inside the class, if the
object's properties and methods belong to that class, allowing for more concise syntax.
Companion object Syntax
Add an extension property
To define an extension property, add the type name and a dot operator
(.) before the variable name.
Add an extension function
To define an extension property, add the type name and a dot operator
(.) before the variable name.
Rewriting extension functions using interfaces
● An interface is defined using the interface keyword, followed by a
name in UpperCamelCase, followed by opening and closing curly
braces.
● Within the curly braces, you can define any method signatures or
get-only properties that any class conforming to the interface must
implement.
Interfaces syntax
● An interface is defined using the interface keyword, followed by a
name in UpperCamelCase, followed by opening and closing curly
braces.
● Within the curly braces, you can define any method signatures or
get-only properties that any class conforming to the interface must
implement.
Extending an Interface
❖ Interfaces allow for variation in the behavior of classes that extend them. It's up to each
class to provide the implementation.
Extending an Interface
❖ Interfaces allow for variation in the behavior of classes that extend them. It's up to each
class to provide the implementation.
Importance of Interfaces
❖ IManual dependency injection. Create an interface defining all the properties and
methods of the dependency. Require the interface as the data type of the
dependency (activity, test case, etc.) so that an instance of any class implementing
the interface can be used. This allows you to swap out the underlying
implementations.
❖ Mocking for automated tests. Both the mock class and the real class conform to the
same interface.
❖ Accessing the same dependencies in a Compose Multi Platform app. For example,
create an interface that provides a common set of properties and methods for
Android and desktop, even if the underlying implementation differs for each
platform.
❖ Several data types in Compose, such as Modifier, are interfaces. This allows you to
add new modifiers without needing to access or modify the underlying source code.
Use scope functions to access class properties
and methods
❖ Scope functions allow you to concisely access properties and methods from a class
without having to repeatedly access the variable name.
❖ They are called scope functions because the body of the function passed in takes
on the scope of the object that the scope function is called with.
❖ For example, some scope functions allow you to access the properties and methods
in a class, as if the functions were defined as a method of that class.
❖ This can make your code more readable by allowing you to omit the object name
when including it is redundant.
Replace long object names using let()
❖ The let() function allows you to refer to an object in a lambda expression using the
identifier it, instead of the object's actual name.
fun printQuiz() {
question1.let {
println(it.questionText)
println(it.answer)
println(it.difficulty)
}
Call an object's methods without a variable using
apply()
❖ The apply() function is an extension function that can be called on an object using
dot notation.
Quiz ().apply {
printQuiz()
}
Use collections in Kotlin
❖ Collection types let you store multiple values, typically of the same data type, in an
organized way.
❖ A collection might be an ordered list, a grouping of unique values, or a mapping of
values of one data type to values of another.
❖ The ability to effectively use collections enables you to implement common
features of Android apps, such as scrolling lists, as well as solve a variety of real-life
programming problems that involve arbitrary amounts of data.
Arrays in Kotlin
❖ An array is a sequence of values that all have the same data type.
❖ An array contains multiple values called elements, or sometimes, items.
❖ The elements in an array are ordered and are accessed with an index.
Arrays in Kotlin
OR
println(solarSystem[3])
Output
Little Earth
Modifying Arrays Example
println(solarSystem[3])
Output
Little Earth
Collections
★ List
★ Set
★ Map
Lists
★ A list is an ordered, resizable collection, typically implemented as a
resizable array.
★ When the array is filled to capacity and you try to insert a new
element, the array is copied to a new bigger array.
The listOf() function
fun main() {
val solarSystem = listOf ("Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune")
}
The listOf() function
fun main() {
val solarSystem = listOf ("Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune")
Get Size
println(solarSystem.size)
Access elements from a list
println(solarSystem[2])
println(solarSystem.get(3))
Find elements by index using indexOf()
println(solarSystem.indexOf("Earth"))
Iterate over list elements using a for loop
Iteration Example
solarSystem.add("Pluto")
At specific Index
solarSystem.add(3, "Theia")
Update elements at a specific index
A set is a collection that does not have a specific order and does not allow duplicate
values.
val solarSystem = mutableSetOf("Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune")
Map collection
"Mercury" to 0 ,
"Venus" to 0 ,
"Earth" to 1 ,
"Mars" to 2 ,
"Jupiter" to 79 ,
"Saturn" to 82 ,
"Uranus" to 27 ,
"Neptune" to 14
println(solarSystem.size)
Map
❖ Arrays store ordered data of the same type, and have a fixed size.
❖ Arrays are used to implement many of the other collection types.
❖ Lists are a resizable, ordered collection.
❖ Sets are unordered collections and cannot contain duplicates.
❖ Maps work similarly to sets and store pairs of keys and values of the specified type.