Kotlin 类 - Kotlin 构造函数
在本教程中,我们将讨论Kotlin 的面向对象编程概念。我们将详细讨论 Kotlin 类。我们还将研究 kotlin 构造函数、访问修饰符和抽象类。
Kotlin 类
类是定义函数和属性的蓝图。Kotlin 中的类使用关键字class
后跟类名来定义。类体位于花括号内。
class FirstClass {
}
该类的实例按以下方式实例化:
val firstClass = FirstClass()
var new = FirstClass() //here new is the name of the var.
与 Java 相反,new
在 Kotlin 中不是关键字。默认情况下,Kotlin 中的类是final 的。因此,Java 中上述定义的等价形式如下:
public final class FirstClass {
}
因此,默认情况下,Kotlin 中的类不可继承。要使类成为非 final 类,我们需要附加关键字open
。
open class Me{
}
该open
注释允许其他人从该类继承。
Kotlin 类示例
让我们创建一个包含几个函数和一个属性的类。我们将了解如何访问该类的函数和属性。此外,我们将了解如何设置成员属性。
class User {
var loggedIn: Boolean = false
val cantChangeValue = "Hi"
fun logOn() {
loggedIn = true
}
fun logOff() {
loggedIn = false
}
}
fun main(args: Array<String>) {
val user = User()
println(user.loggedIn) //false
user.logOn()
println(user.loggedIn) //true
user.logOff()
println(user.loggedIn) //false
user.cantChangeValue = "Hey" //won't compile. Can't modify a final variable.
}
该函数main
属于Test.kt
类。要访问成员和函数,我们需要使用点运算符。val
不能使用点运算符再次设置属性。
Kotlin 初始化
Kotlin init 块定义如下所示。
class User {
init{
print("Class instance is initialised.")
}
var loggedIn: Boolean = false
val cantChangeValue = "Hi"
fun logOn() {
loggedIn = true
}
fun logOff() {
loggedIn = false
}
}
块内的代码init
是类实例化时首先执行的代码。init
每次实例化类时都会运行该块,使用任何类型的构造函数,我们将在下文中看到。可以在一个类中编写多个初始化块。它们将按顺序执行,如下所示。
class MultiInit(name: String) {
init {
println("First initializer block that prints ${name}")
}
init {
println("Second initializer block that prints ${name.length}")
}
}
fun main(args: Array<String>) {
var multiInit = MultiInit("Kotlin")
}
//Following is printed in the log console.
//First initializer block that prints Kotlin
//Second initializer block that prints 6
Kotlin 类允许使用函数在声明本身中打印属性also
,如下所示。
class MultiInit(name: String) {
val firstProperty = "First property: $name".also(::println)
init {
println("First initializer block that prints ${name}")
}
val secondProperty = "Second property: ${name.length}".also(::println)
init {
println("Second initializer block that prints ${name.length}")
}
}
fun main(args: Array<String>) {
var multiInit = MultiInit("Kotlin")
}
//Following gets printed.
//First property: Kotlin
//First initializer block that prints Kotlin
//Second property: 6
//Second initializer block that prints 6
Kotlin 构造函数
Kotlin 构造函数是用于初始化属性的特殊成员函数。Kotlin 中的构造函数的编写和结构与 Java 不同。默认情况下,类有一个空的构造函数,如下所示:
class Student {
var name: String
val age : Int
init {
name = "Anupam"
age = 24
}
init {
name = "Anupam Chugh"
//age = 26
}
}
fun main(args: Array<String>) {
val student = Student()
println("${student.name} age is ${student.age}")
student.name = "Your"
//student.age = 26 //won't compile. age is val
println("${student.name} age is ${student.age}")
}
//Following is printed on the console:
//Anupam Chugh age is 24
//Your age is 24
主要构造函数
Kotlin 中的主要构造函数在类头本身中定义,如下所示。
class User(var name: String, var isAdmin: Boolean) {
init {
name = name + " @ JournalDev.com"
println("Author Name is $name. Is Admin? $isAdmin")
}
}
主构造函数定义位于类标头内。我们在构造函数本身中定义了属性类型(val/var)。注意:除非声明为var
,否则默认情况下,构造函数参数为val
。
class User(name: String, isAdmin: Boolean)
在上面的代码中,name 和 isAdmin 都不能重新赋值。或者,我们也可以将构造函数参数分配给类中的成员属性,如下所示。
class User(name: String, val isAdmin: Boolean) {
var username = name
val _isAdmin = isAdmin
init {
username= username + " @ JournalDev.com"
println("Author Name is $name. Is Admin? $_isAdmin")
}
}
fun main(args: Array<String>) {
var user = User("Anupam",false)
user.isAdmin = true //won't compile since isAdmin is val
user._isAdmin = true //won't compile. Same reason.
user = User("Pankaj",true)
}
//Following is printed in the log console.
//Author Name is Anupam. Is Admin? false
//Author Name is Pankaj. Is Admin? true
Kotlin 构造函数默认值
Kotlin 允许我们在构造函数本身中指定默认值,如下所示。
class User(name: String, var website: String = "JournalDev") {
init {
println("Author $name writes at $website")
}
init {
website = website + ".com"
println("Author $name writes at $website")
}
}
fun main(args: Array<String>) {
var user = User("Anupam","JournalDev")
user = User("Pankaj","JournalDev")
}
//Following is printed on the console:
//Author Anupam writes at JournalDev
//Author Anupam writes at JournalDev.com
//Author Pankaj writes at JournalDev
//Author Pankaj writes at JournalDev.com
次要构造函数
二级构造函数在类体内部以关键字 为前缀进行书写constructor
。以下示例演示了这一点。
class Student {
var name: String
val age : Int
constructor(name: String, age: Int)
{
this.name = name
this.age = age
}
fun printDetails()
{
println("Name is $name and Age is $age")
}
}
fun main(args: Array<String>) {
var student = Student("Anupam", 24)
student.printDetails()
}
//Following is printed in the console.
//Name is Anupam and Age is 24
The most common usage of secondary constructors comes in subclasses when you need to initialize the class in different ways. If the class contains a primary constructor, the secondary constructor must refer to it in its declaration. The declaration is done using this
keyword.
class Student(var name: String, val age: Int) {
var skill: String
init {
skill = "NA"
}
constructor(name: String, age: Int, skill: String) : this(name, age) {
this.skill = skill
}
fun printDetails() {
if (skill.equals("NA"))
println("Name is $name and Age is $age")
else
println("Name is $name and Age is $age Skill is $skill")
}
}
//Following is printed in the log console:
//Name is Anupam and Age is 24
//Name is Anupam and Age is 24 Skill is Kotlin
init
block is used to initialise the member property skill
. The secondary constructor delegates to the primary constructor using : this
.
Custom Getter and Setters
Up until now we’ve accessed and modified properties in a class using the dot operator on the instance of the class. Let’s use set
and get
syntax to see how we can customise the access.
class Name{
var post: String = "default"
set(value) {if(!post.isNotEmpty()) {
throw IllegalArgumentException(" Enter a valid name")
}
field = value
print(value)
}
}
fun main(args: Array<String>) {
var name = Name()
name.post = "Kotlin Classes"
name.post = ""
name.post = "Kotlin Data Classes Our Next Tutorial"
}
Following is printed in the log console:
Kotlin Classes
Exception in thread "main" java.lang.IllegalArgumentException: Enter a valid name
at Name.setPost(Test.kt:16)
at TestKt.main(Test.kt:78)
The field
variable in the setter saves the older value. Let’s add a getter.
class Name{
var post: String = "default"
set(value) {if(!post.isNotEmpty()) {
throw IllegalArgumentException(" Enter a valid name")
}
field = value
}
get() {
return field.capitalize()
}
}
fun main(args: Array<String>) {
var name = Name()
name.post = "kotlin classes"
println(name.post)
name.post = "kotlin data Classes our next Tutorial"
println(name.post)
}
//Following is printed:
//Kotlin classes
//Kotlin data Classes our next Tutorial
capitalize()
capitalizes the first letter of the string. Note: if the property is a val
, set
method won’t compile.
Kotlin Visibility Modifier
- Public : Any class, function, property, interface, or object that has this modifier is visible and can be accessed from anywhere.
- Private: A class/function defined with this modifier can be only accessed within the same file. A member/property in a class/function with this modifier can be only accessed within that block.
- Protected : This modifier is same as private, except that it allows visibility and access within subclasses.
- Internal: A class/interface/function with this modifier is accessible only within the same module.
Visibility Modifiers are applicable on Constructors as well. Assigning a modifier to a Primary Constructor requires us to specify the keyword constructor
alongside the constructor in the class header.
class Student private constructor (var name: String, val age: Int) {
var skill: String
init {
skill = "NA"
}
constructor(name: String, age: Int, skill: String) : this(name, age) {
this.skill = skill
}
fun printDetails() {
if (skill.equals("NA"))
println("Name is $name and Age is $age")
else
println("Name is $name and Age is $age Skill is $skill")
}
}
fun main(args: Array<String>) {
var student = Student("Anupam",24,"Kotlin")
student.printDetails()
}
//prints
//Name is Anupam and Age is 24 Skill is Kotlin
Private constructors can’t be called outside the class. In the above code, we can instantiate the class in a different function only using the secondary constructor.
Kotlin Abstract Class
Like Java, abstract
keyword is used to declare abstract classes in Kotlin. An Abstract class can’t be instantiated. However, it can be inherited by subclasses. By default, the members of an abstract class are non-abstract unless stated otherwise.
abstract class Person(name: String) {
init {
println("Abstract Class. init block. Person name is $name")
}
abstract fun displayAge()
}
class Teacher(name: String): Person(name) {
var age : Int
init {
age = 24
}
override fun displayAge() {
println("Non-abstract class displayAge function overridden. Age is $age")
}
}
fun main(args: Array<String>) {
val person = Teacher("Anupam")
person.displayAge()
}
//Following is printed in the console.
//Abstract Class. init block. Person name is Anupam
//Non-abstract class. Age is 24
Note: Abstract classes are by default open
. So adding an open modifier to allow subclassing isn’t required. override
keyword is used to override a method in the subclass. We’ve covered the basics of kotlin classes in this tutorial. There’s a lot more still there such as Data Classes, Sealed Classes, Inheritance etc. We’ll be covering them in the upcoming tutorials. References : Kotlin Docs