Kotlin类– Kotlin构造函数

时间:2020-02-23 14:37:29  来源:igfitidea点击:

在本教程中,我们将讨论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中的类是不可继承的。

为了使一个类不是最终类,我们需要添加关键字" 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初始化块的定义如下所示。

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类通过使用"如下"函数也允许在声明本身中打印属性,如下所示。

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构造函数是用于初始化属性的特殊成员函数。
与Java相比,Kotlin中的构造函数的编写和结构有所不同。
默认情况下,一个类的空构造函数如下所示:

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 + " @ theitroad.local"
      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 + " @ theitroad.local"
      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("hyman",true)
}

//Following is printed in the log console.
//Author Name is Anupam. Is Admin? false
//Author Name is hyman. Is Admin? true

Kotlin构造函数默认值

Kotlin允许我们在构造函数本身中指定默认值,如下所示。

class User(name: String, var website: String = "theitroad") {

  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","theitroad")
  user = User("hyman","theitroad")
}

//Following is printed on the console:
//Author Anupam writes at theitroad
//Author Anupam writes at theitroad.local
//Author hyman writes at theitroad
//Author hyman writes at theitroad.local

二级构造函数

二级构造函数以关键字" 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

当您需要以不同方式初始化类时,辅助构造函数最常见的用法是出现在子类中。

如果该类包含一个主构造函数,则该辅助构造函数必须在其声明中引用它。
声明是通过this关键字完成的。

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"块用于初始化成员属性" skill"。
次要构造函数使用:this委托给主要构造函数。

自定义获取器和设置器

到目前为止,我们已经使用类实例上的点运算符访问和修改了类中的属性。
让我们使用set和get语法来了解如何自定义访问权限。

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"

}

在日志控制台中打印以下内容:

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)

设置器中的" field"变量将保存较早的值。
让我们添加一个吸气剂。

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()将字符串的首字母大写。

注意:如果属性为val,则不会编译set方法。

Kotlin可见性修改器

  • Public:任何具有此修饰符的类,函数,属性,接口或者对象都是可见的,可以从任何地方访问。

  • 专用:用此修饰符定义的类/函数只能在同一文件中访问。
    带有此修饰符的类/函数中的成员/属性只能在该块内访问。

  • 受保护的:此修饰符与私有修饰符相同,不同之处在于它允许在子类中进行可见性和访问。

  • 内部:具有此修饰符的类/接口/功能只能在同一模块中访问。

可见性修饰符也适用于构造函数。
为主要构造函数分配修饰符需要我们在类标题中的构造函数旁边指定关键字" constructor"。

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

私人构造函数不能在课堂外调用。
在上面的代码中,我们只能使用辅助构造函数在另一个函数中实例化该类。

Kotlin抽象课

与Java类似,abstract关键字用于声明Kotlin中的抽象类。
Abstract类无法实例化。
但是,它可以被子类继承。
默认情况下,除非另有说明,否则抽象类的成员是非抽象的。

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

注意:抽象类默认为" open"。
因此,不需要添加open修饰符以允许子类化。

" override"关键字用于覆盖子类中的方法。