Kotlin - 快速指南


Kotlin - 概述

Kotlin 是一种新的开源编程语言,如 Java、JavaScript 等。它是一种高级强静态类型语言,将功能和技术部分结合在同一个地方。目前,Kotlin 的目标是 Java 和 JavaScript。它运行在 JVM 上。

Kotlin 受到 Java、Scala、Groovy、Gosu 等其他编程语言的影响。Kotlin 的语法可能与 JAVA 并不完全相似,但是,Kotlin 内部依赖于现有的 Java 类库,为程序员提供了精彩的结果。Kotlin 为世界各地的开发人员提供互操作性、代码安全性和清晰度。

的优点和缺点

以下是使用 Kotlin 进行应用程序开发的一些优势。

Easy Language - Kotlin 是一种函数式语言,非常容易学习。语法与Java非常相似,因此很容易记住。Kotlin 更具表现力,这使您的代码更具可读性和可理解性。

简洁- Kotlin 基于 JVM,它是一种函数式语言。因此,它减少了其他编程语言中使用的大量样板代码。

运行时和性能- 更好的性能和更小的运行时间。

互操作性- Kotlin 足够成熟,可以以不太复杂的方式构建可互操作的应用程序。

全新- Kotlin 是一种全新的语言,为开发人员提供了一个全新的开始。尽管它是在 JVM 上开发的,但它并不是 Java 的替代品。它被接受为 Android 开发的第一个官方语言。Kotlin 可以定义为 - Kotlin = JAVA + 额外更新的新功能。

以下是 Kotlin 的一些缺点。

命名空间声明- Kotlin 允许开发人员在顶层声明函数。然而,每当在应用程序的许多地方声明相同的函数时,就很难理解正在调用哪个函数。

无静态声明- Kotlin 没有像 Java 那样常见的静态处理修饰符,这可能会给传统 Java 开发人员带来一些问题。

Kotlin - 环境设置

但是,如果您仍然想在本地系统中离线使用 Kotlin,那么您需要执行以下步骤来配置本地工作区。

步骤 1 - Java 8 安装。

因此,Kotlin 在 JVM 上运行。本地 Kotlin 开发确实有必要使用 JDK 8。请参考oracle官网下载并安装JDK 8或以上版本。您可能需要设置JAVA的环境变量才能使其正常工作。要验证 Windows 操作系统中的安装,请在命令提示符中点击“java –version”,作为输出,它将显示系统中安装的 java 版本。

步骤 2 - IDE 安装。

Internet 上有许多可用的 IDE。您可以使用您选择的任何一个。您可以在下表中找到不同IDE的下载链接。

始终建议使用最新的软件版本,以从中发挥最大的功能。

步骤 3 - 配置 Eclipse。

打开 Eclipse 并转到“Eclipse Market Place”。您将看到以下屏幕。

日食市场

在搜索框中搜索 Kotlin 并将其安装在本地系统中。这可能需要一些时间,具体取决于互联网速度。成功安装后,您可能需要重新启动 Eclipse。

步骤 4 - Kotlin 项目。

成功重新启动 Eclipse 并安装 Kotlin 后,您将能够动态创建 Kotlin 项目。转到文件 → 新建 → 其他并从列表中选择“Kotlin 项目”。

Kotlin 项目

项目设置完成后,您可以在“SRC”文件夹下创建一个 Kotlin 文件。左键单击“Src”文件夹,然后单击“新建”。您将获得 Kotlin 文件的选项,否则您可能需要从“其他”中搜索。创建新文件后,您的项目目录将如下所示。

你好

您的开发环境现已准备就绪。继续在“Hello.kt”文件中添加以下代码。

现场演示
fun main(args: Array<String>) {
   println("Hello, World!")
}

将其作为 Kotlin 应用程序运行,并在控制台中查看输出,如以下屏幕截图所示。为了更好地理解和可用性,我们将使用我们的编码基础工具。

Hello, World!

Kotlin - 架构

Kotlin 是一种编程语言,拥有自己的架构来分配内存并向最终用户生成高质量的输出。以下是 Kotlin 编译器在针对不同的其他类型语言(例如 Java 和 JavaScript)时会以不同方式工作的不同场景。

Kotlin 编译器创建字节码,该字节码可以在 JVM 上运行,它与 Java .class文件生成的字节码完全相同。每当两个字节编码文件在 JVM 上运行时,它们就可以相互通信,这就是 Kotlin for Java 中建立可互操作功能的方式。

建筑学

每当 Kotlin 以 JavaScript 为目标时,Kotlin 编译器都会将.kt文件转换为 ES5.1 并生成与 JavaScript 兼容的代码。Kotlin 编译器能够通过 LLVM 创建基于平台的兼容代码。

Kotlin - 基本类型

在本章中,我们将了解 Kotlin 编程语言中可用的基本数据类型。

数字

Kotlin 中数字的表示与 Java 非常相似,但是,Kotlin 不允许不同数据类型的内部转换。下表列出了不同数字的不同变量长度。

类型 尺寸
双倍的 64
漂浮 32
长的 64
INT 32
短的 16
字节 8

在下面的示例中,我们将了解 Kotlin 如何处理不同的数据类型。请在我们的编码区中输入以下一组代码。

现场演示
fun main(args: Array<String>) {
   val a: Int = 10000
   val d: Double = 100.00
   val f: Float = 100.00f
   val l: Long = 1000000004
   val s: Short = 10
   val b: Byte = 1
   
   println("Your Int Value is "+a);
   println("Your Double  Value is "+d);
   println("Your Float Value is "+f);
   println("Your Long Value is "+l);
   println("Your Short Value is "+s);
   println("Your Byte Value is "+b);
}

当您在编码区运行上述代码时,它将在 Web 控制台中生成以下输出。

Your Int Value is 10000
Your Double  Value is 100.0
Your Float Value is 100.0
Your Long Value is 1000000004
Your Short Value is 10
Your Byte Value is 1

人物

Kotlin 使用char表示字符。字符应该用单引号声明,例如'c'。请在我们的编码区中输入以下代码,看看 Kotlin 如何解释字符变量。字符变量不能像数字变量一样声明。Kotlin 变量可以通过两种方式声明 - 一种使用“var”,另一种使用“val”

现场演示
fun main(args: Array<String>) {
   val letter: Char    // defining a variable 
   letter = 'A'        // Assigning a value to it 
   println("$letter")
}

上面的代码将在浏览器输出窗口中产生以下输出。

A

布尔值

布尔与其他编程语言一样非常简单。我们只有两个布尔值——true 或 false。在下面的示例中,我们将看到 Kotlin 如何解释布尔值。

现场演示
fun main(args: Array<String>) {
   val letter: Boolean   // defining a variable 
   letter = true         // Assinging a value to it 
   println("Your character value is "+"$letter")
}

上面的代码将在浏览器中产生以下输出。

Your character value is true

弦乐

字符串是字符数组。与 Java 一样,它们本质上是不可变的。Kotlin 中有两种可用的字符串 - 一种称为原始字符串,另一种称为转义字符串。在下面的示例中,我们将使用这些字符串。

现场演示
fun main(args: Array<String>) {
   var rawString :String  = "I am Raw String!"
   val escapedString : String  = "I am escaped String!\n"
   
   println("Hello!"+escapedString)
   println("Hey!!"+rawString)   
}

上面的转义字符串示例允许在第一个打印语句之后提供额外的行空间。以下将是浏览器中的输出。

Hello!I am escaped String!

Hey!!I am Raw String!

数组

数组是同质数据的集合。与 Java 一样,Kotlin 支持不同数据类型的数组。在下面的示例中,我们将使用不同的数组。

现场演示
fun main(args: Array<String>) {
   val numbers: IntArray = intArrayOf(1, 2, 3, 4, 5)
   println("Hey!! I am array Example"+numbers[2])
}

上面的代码产生以下输出。数组的索引与其他编程语言类似。在这里,我们正在搜索第二个索引,其值为“3”。

Hey!! I am array Example3

收藏

集合是数据结构中非常重要的一部分,它使工程师的软件开发变得容易。Kotlin 有两种类型的集合 - 一种是不可变集合(这意味着无法编辑的列表、映射和集合),另一种是可变集合(这种类型的集合是可编辑的)。记住应用程序中使用的集合类型非常重要,因为 Kotlin 系统并不代表它们之间的任何特定差异。

现场演示
fun main(args: Array<String>) { 
   val numbers: MutableList<Int> = mutableListOf(1, 2, 3) //mutable List 
   val readOnlyView: List<Int> = numbers                  // immutable list 
   println("my mutable list--"+numbers)        // prints "[1, 2, 3]" 
   numbers.add(4) 
   println("my mutable list after addition --"+numbers)        // prints "[1, 2, 3, 4]" 
   println(readOnlyView)     
   readOnlyView.clear()    // ⇒ does not compile  
// gives error  
}

上面的代码将在浏览器中产生以下输出。当我们尝试清除集合的可变列表时,它会给出错误。

main.kt:9:18: error: unresolved reference: clear
   readOnlyView.clear()    // -> does not compile  
                 ^

在集合方面,Kotlin 提供了一些有用的方法,例如first()、last()、filter()等。所有这些方法都是自描述性的并且易于实现。而且,Kotlin 在实现集合时遵循与 Java 相同的结构。您可以自由地实现您选择的任何集合,例如 Map 和 Set。

在下面的示例中,我们使用不同的内置方法实现了 Map 和 Set。

现场演示
fun main(args: Array<String>) {
   val items = listOf(1, 2, 3, 4)
   println("First Element of our list----"+items.first())
   println("Last Element of our list----"+items.last())
   println("Even Numbers of our List----"+items.
      filter { it % 2 = = 0 })   // returns [2, 4]
   
   val readWriteMap = hashMapOf("foo" to 1, "bar" to 2)
   println(readWriteMap["foo"])  // prints "1"
   
   val strings = hashSetOf("a", "b", "c", "c")
   println("My Set Values are"+strings)
}

上面的代码在浏览器中产生以下输出。

First Element of our list----1
Last Element of our list----4
Even Numbers of our List----[2, 4]
1
My Set Values are[a, b, c]

范围

范围是 Kotlin 的另一个独特特性。与 Haskell 一样,它提供了一个运算符来帮助您迭代范围。在内部,它是使用rangeTo()实现的,其运算符形式为(..)

在下面的示例中,我们将看到 Kotlin 如何解释这个范围运算符。

现场演示
fun main(args: Array<String>) {
   val i:Int  = 2
   for (j in 1..4) 
   print(j) // prints "1234"
   
   if (i in 1..10) { // equivalent of 1 < = i && i < = 10
      println("we found your number --"+i)
   }
}

上面的代码在浏览器中产生以下输出。

1234we found your number --2

Kotlin - 控制流

在上一章中,我们了解了 Kotlin 系统中可用的不同类型的数据类型。在本章中,我们将讨论 Kotlin 中可用的不同类型的控制流机制。

如果别的

Kotlin 是一种函数式语言,因此就像 Kotlin 中的每个函数式语言一样,“if”是一个表达式,它不是一个关键字。表达式“if”将在必要时返回一个值。与其他编程语言一样,“if-else”块用作初始条件检查运算符。在下面的示例中,我们将比较两个变量并相应地提供所需的输出。

现场演示
fun main(args: Array<String>) {
   val a:Int = 5
   val b:Int = 2
   var max: Int
   
   if (a > b) {
      max = a
   } else {
      max = b
   }
   print("Maximum of a or b is " +max)
 
   // As expression 
   // val max = if (a > b) a else b
}

上面的代码在浏览器中产生以下输出结果。我们的示例还包含另一行代码,它描述了如何使用“If”语句作为表达式。

Maximum of a or b is 5

使用何时

如果您熟悉其他编程语言,那么您可能听说过术语 switch 语句,它基本上是一个条件运算符,可以将多个条件应用于特定变量。“when”运算符将变量值与分支条件进行匹配。如果满足分支条件,那么它将执行该范围内的语句。在下面的例子中,我们将更多地了解 Kotlin 中的“when”。

现场演示
fun main(args: Array<String>) {
   val x:Int = 5
   when (x) {
      1 -> print("x = = 1")
      2 -> print("x = = 2")
      
      else -> { // Note the block
         print("x is neither 1 nor 2")
      }
   }
}

上面的代码在浏览器中产生以下输出。

x is neither 1 nor 2

在上面的示例中,Kotlin 编译器将x的值与给定的分支进行匹配。如果它不匹配任何分支,那么它将执行 else 部分。实际上,when 相当于多个if 块。Kotlin 为开发人员提供了另一种灵活性,开发人员可以通过在检查内提供“,”在同一行中提供多个检查。让我们将上面的例子修改如下。

现场演示
fun main(args: Array<String>) {
   val x:Int = 5
   when (x) {
      1,2 -> print(" Value of X either 1,2")
      
      else -> { // Note the block
         print("x is neither 1 nor 2")
      }
   }
}

在浏览器中运行相同的命令,这将在浏览器中产生以下输出。

x is neither 1 nor 2

For循环

循环就是这样一种发明,它提供了遍历任何类型的数据结构的灵活性。与其他编程语言一样,Kotlin 也提供了多种 Looping 方法,但其中“For”是最成功的一种。For 循环的实现和使用在概念上与Java for 循环类似。下面的例子展示了我们如何在现实生活中使用它。

现场演示
fun main(args: Array<String>) {
   val items = listOf(1, 2, 3, 4)
   for (i in items) println("values of the array"+i)
}

在上面的代码中,我们声明了一个名为“items”的列表,并使用 for 循环迭代该定义的列表并在浏览器中打印其值。以下是输出。

values of the array1
values of the array2
values of the array3
values of the array4

下面是另一个代码示例,我们使用一些库函数来使我们的开发工作比以前更容易。

现场演示
fun main(args: Array<String>) {
   val items = listOf(1, 22, 83, 4)
   
   for ((index, value) in items.withIndex()) {
      println("the element at $index is $value")
   }
}

一旦我们在编码环境中编译并执行上述代码,它将在浏览器中产生以下输出。

the element at 0 is 1
the element at 1 is 22
the element at 2 is 83
the element at 3 is 4

While 循环和Do-While 循环

While 和 Do-While 的工作方式与其他编程语言中的工作方式完全相同。这两个循环之间的唯一区别是,在 Do-while 循环的情况下,将在循环结束时测试条件。以下示例显示了While 循环的用法。

现场演示
fun main(args: Array<String>) {
   var x:Int = 0
   println("Example of While Loop--")
   
   while(x< = 10) {
      println(x)
      x++
   } 
}

上面的代码在浏览器中产生以下输出。

Example of While Loop--
0
1
2
3
4
5
6
7
8
9
10

Kotlin 还有另一个循环,称为 Do-While 循环,其中循环体将被执行一次,然后才会检查条件。以下示例显示了Do-while 循环的用法。

现场演示
fun main(args: Array<String>) {
   var x:Int = 0
   do {
      x = x + 10
      println("I am inside Do block---"+x)
   } while(x <= 50)
}

上面的代码在浏览器中产生以下输出。在上面的代码中,Kotlin 编译器将执行 DO 块,然后在 while 块中进行条件检查。

I am inside Do block---10
I am inside Do block---20
I am inside Do block---30
I am inside Do block---40
I am inside Do block---50
I am inside Do block---60

使用 Return、Break、Continue

如果您熟悉任何编程语言,那么您必须了解不同的关键字,以帮助我们在应用程序中实现良好的控制流。以下是可用于控制循环或任何其他类型的控制流的不同关键字。

Return - Return 是一个关键字,它将一些值从被调用函数返回到调用函数。在下面的示例中,我们将使用 Kotlin 编码基础来实现此场景。

现场演示
fun main(args: Array<String>) {
   var x:Int = 10
   println("The value of X is--"+doubleMe(x))
}
fun doubleMe(x:Int):Int {
   return 2*x;
}

在上面的代码中,我们调用另一个函数并将输入乘以 2,并将结果值返回给被调用的函数,即我们的主函数。Kotlin 以不同的方式定义该函数,我们将在后续章节中讨论。现在,只要理解上面的代码将在浏览器中生成以下输出就足够了。

The value of X is--20

继续和中断- 继续和中断是逻辑问题中最重要的部分。如果某些条件失败,“break”关键字将终止控制器流程,而“Continue”则执行相反的操作。所有这些操作都是在即时可见的情况下进行的。Kotlin 比其他编程语言更智能,开发人员可以应用多个标签作为可见性。下面的代码展示了我们如何在 Kotlin 中实现这个标签。

现场演示
fun main(args: Array<String>) {
   println("Example of Break and Continue")
   myLabel@ for(x in 1..10) { // appling the custom label
      if(x = = 5) {
         println("I am inside if block with value"+x+"\n-- hence it will close the operation")
         break@myLabel //specifing the label
      } else {
         println("I am inside else block with value"+x)
         continue@myLabel
      }
   }
}

上面的代码在浏览器中产生以下输出。

Example of Break and Continue
I am inside else block with value1
I am inside else block with value2
I am inside else block with value3
I am inside else block with value4
I am inside if block with value5
-- hence it will close the operation

正如你所看到的,控制器继续循环,直到并且除非x的值是5。一旦x的值达到5,它开始执行if块,一旦到达break语句,整个控制流终止程序执行。

Kotlin - 类和对象

在本章中,我们将学习使用 Kotlin 进行面向对象编程 (OOP) 的基础知识。我们将学习类及其对象以及如何使用该对象。根据 OOP 的定义,类是运行时实体的蓝图,对象是其状态,包括其Behave和状态。在 Kotlin 中,类声明由类头和类体组成,类体由大括号括起来,与 Java 类似。

Class myClass { // class Header 

   // class Body
}

与 Java 一样,Kotlin 也允许创建一个类的多个对象,并且您可以自由地包含其类成员和函数。我们可以使用我们将在第 10 章 - 可见性控制中学习的不同关键字来控制类成员变量的可见性。在下面的示例中,我们将创建一个类及其对象,通过该对象我们将访问该类的不同数据成员。

现场演示
class myClass {
   // property (data member)
   private var name: String = "Tutorials.point"
   
   // member function
   fun printMe() {
      print("You are at the best Learning website Named-"+name)
   }
}
fun main(args: Array<String>) {
   val obj = myClass() // create obj object of myClass class
   obj.printMe()
}

上面的代码将在浏览器中产生以下输出,其中我们使用 myClass 自己的对象调用 printMe() 。

You are at the best Learning website Named- Tutorials.point

嵌套类

根据定义,当一个类在另一个类中创建时,它被称为嵌套类。在 Kotlin 中,嵌套类默认是静态的,因此可以在不创建该类的任何对象的情况下访问它。在下面的示例中,我们将看到 Kotlin 如何解释我们的嵌套类。

现场演示
fun main(args: Array<String>) {
   val demo = Outer.Nested().foo() // calling nested class method
   print(demo)
}
class Outer {
   class Nested {
      fun foo() = "Welcome to The TutorialsPoint.com"
   }
}

上面的代码将在浏览器中产生以下输出。

Welcome to The TutorialsPoint.com

内部类

当嵌套类被标记为“内部”时,它将被称为内部类。内部类可以通过外部类的数据成员来访问。在下面的示例中,我们将访问外部类的数据成员。

现场演示
fun main(args: Array<String>) {
   val demo = Outer().Nested().foo() // calling nested class method
   print(demo)
}
class Outer {
   private val welcomeMessage: String = "Welcome to the TutorialsPoint.com"
   inner class Nested {
      fun foo() = welcomeMessage
   }
}

上面的代码将在浏览器中产生以下输出,其中我们使用 Kotlin 编译器在编译时提供的默认构造函数来调用嵌套类。

Welcome to the TutorialsPoint.com

匿名内部类

匿名内部类是一个非常好的概念,它使程序员的生活变得非常轻松。每当我们实现一个接口时,匿名内部块的概念就会出现。使用运行时对象引用创建接口对象的概念称为匿名类。在下面的示例中,我们将创建一个接口,并使用匿名内部类机制创建该接口的对象。

现场演示
fun main(args: Array<String>) {
   var programmer :Human = object:Human // creating an instance of the interface {
      override fun think() { // overriding the think method
         print("I am an example of Anonymous Inner Class ")
      }
   }
   programmer.think()
}
interface Human {
   fun think()
}

上面的代码将在浏览器中产生以下输出。

I am an example of Anonymous Inner Class 

类型别名

类型别名是 Kotlin 编译器的一个属性。它提供了创建现有类型的新名称的灵活性,但它不创建新类型。如果类型名称太长,您可以轻松引入较短的名称并在将来使用时使用相同的名称。类型别名对于复杂类型确实很有帮助。在最新版本中,Kotlin 取消了对类型别名的支持,但是,如果您使用的是旧版本的 Kotlin,您可能会像下面这样使用它 -

typealias NodeSet = Set<Network.Node>
typealias FileTable<K> = MutableMap<K, MutableList<File>>

Kotlin - 构造函数

在本章中,我们将学习 Kotlin 中的构造函数。Kotlin 有两种类型的构造函数 - 一种是主构造函数,另一种是辅助构造函数。一个 Kotlin 类可以有一个主构造函数和一个或多个辅助构造函数。Java 构造函数初始化成员变量,但是,在 Kotlin 中,主构造函数初始化类,而辅助构造函数有助于在初始化类时包含一些额外的逻辑。主构造函数可以在类头级别声明,如下例所示。

class Person(val firstName: String, var age: Int) {
   // class body
}

在上面的示例中,我们在括号内声明了主构造函数。在这两个字段中,名字是只读的,因为它被声明为“val”,而字段年龄可以编辑。在下面的示例中,我们将使用主构造函数。

现场演示
fun main(args: Array<String>) {
   val person1 = Person("TutorialsPoint.com", 15)
   println("First Name = ${person1.firstName}")
   println("Age = ${person1.age}")
}
class Person(val firstName: String, var age: Int) {
}

上面的代码将自动初始化这两个变量并在浏览器中提供以下输出。

First Name = TutorialsPoint.com
Age = 15

如前所述,Kotlin 允许为您的类创建一个或多个辅助构造函数。这个辅助构造函数是使用“constructor”关键字创建的。每当您想要在 Kotlin 中创建多个构造函数,或者每当您想要在主构造函数中包含更多逻辑,但您无法这样做,因为主构造函数可能会被其他某个类调用时,就需要使用它。看一下下面的示例,我们创建了一个辅助构造函数,并使用上面的示例来实现相同的构造函数。

现场演示
fun main(args: Array<String>) {
   val HUman = HUman("TutorialsPoint.com", 25)
   print("${HUman.message}"+"${HUman.firstName}"+
      "Welcome to the example of Secondary  constructor, Your Age is-${HUman.age}")
}
class HUman(val firstName: String, var age: Int) {
   val message:String  = "Hey!!!"
	constructor(name : String , age :Int ,message :String):this(name,age) {
   }
}

注意- 可以创建任意数量的辅助构造函数,但是,所有这些构造函数都应直接或间接调用主构造函数。

上面的代码将在浏览器中产生以下输出。

Hey!!! TutorialsPoint.comWelcome to the example of Secondary  constructor, Your Age is- 25

Kotlin - 继承

在本章中,我们将学习继承。根据定义,我们都知道继承意味着将母类的某些属性添加到子类中。在 Kotlin 中,基类被命名为“Any”,它是 Kotlin 中声明的“any”默认类的超类。与所有其他 OOPS 一样,Kotlin 也使用一个名为“:”的关键字提供此功能。

Kotlin 中的所有内容默认都是 Final 的,因此,我们需要在类声明前面使用关键字“open”以使其允许继承。看一下下面的继承示例。

现场演示
import java.util.Arrays

open class ABC {
   fun think () {
      print("Hey!! i am thiking ")
   }
}
class BCD: ABC(){ // inheritence happend using default constructor 
}

fun main(args: Array<String>) {
   var  a = BCD()
   a.think()
}

上面的代码将在浏览器中产生以下输出。

Hey!! i am thiking 

现在,如果我们想重写子类中的 think() 方法该怎么办?然后,我们需要考虑以下示例,其中我们创建两个类并将其函数之一重写到子类中。

现场演示
import java.util.Arrays

open class ABC {
   open fun think () {
      print("Hey!! i am thinking ")
   }
}
class BCD: ABC() { // inheritance happens using default constructor 
   override fun think() {
      print("I Am from Child")
   }
}
fun main(args: Array<String>) {
   var  a = BCD()
   a.think()
}

上面的代码将调用子类继承的方法,并将在浏览器中产生以下输出。与 Java 一样,Kotlin 也不允许多重继承。

I Am from Child 

Kotlin - 接口

在本章中,我们将学习 Kotlin 中的接口。在 Kotlin 中,接口的工作方式与 Java 8 完全相同,这意味着它们可以包含方法实现以及抽象方法声明。接口可以由类实现,以便使用其定义的功能。我们已经在第 6 章“匿名内部类”部分介绍了一个带有接口的示例。在本章中,我们将了解更多相关内容。关键字“interface”用于在 Kotlin 中定义接口,如以下代码所示。

interface ExampleInterface {
   var myVar: String     // abstract property
   fun absMethod()       // abstract method
   fun sayHello() = "Hello there" // method with default implementation
}

在上面的示例中,我们创建了一个名为“ExampleInterface”的接口,其中包含一些抽象属性和方法。看一下名为“sayHello()”的函数,它是一个已实现的方法。

在下面的示例中,我们将在类中实现上述接口。

现场演示
interface ExampleInterface  {
   var myVar: Int            // abstract property
   fun absMethod():String    // abstract method
   
   fun hello() {
      println("Hello there, Welcome to TutorialsPoint.Com!")
   }
}
class InterfaceImp : ExampleInterface {
   override var myVar: Int = 25
   override fun absMethod() = "Happy Learning "
}
fun main(args: Array<String>) {
   val obj = InterfaceImp()
   println("My Variable Value is = ${obj.myVar}")
   print("Calling hello(): ")
   obj.hello()
   
   print("Message from the Website-- ")
   println(obj.absMethod())
}

上面的代码将在浏览器中产生以下输出。

My Variable Value is = 25
Calling hello(): Hello there, Welcome to TutorialsPoint.Com!
Message from the Website-- Happy Learning 

正如前面提到的,Kotlin 不支持多重继承,但是,可以通过同时实现两个以上的接口来实现同样的效果。

在下面的示例中,我们将创建两个接口,稍后我们将这两个接口实现到一个类中。

现场演示
interface A {
   fun printMe() {
      println(" method of interface A")
   }
}
interface B  {
   fun printMeToo() {
      println("I am another Method from interface B")
   }
}

// implements two interfaces A and B
class multipleInterfaceExample: A, B

fun main(args: Array<String>) {
   val obj = multipleInterfaceExample()
   obj.printMe()
   obj.printMeToo()
}

在上面的示例中,我们创建了两个示例接口 A、B,并且在名为“multipleInterfaceExample”的类中,我们实现了之前声明的两个接口。上面的代码将在浏览器中产生以下输出。

method of interface A
I am another Method from interface B

Kotlin - 可见性控制

在本章中,我们将了解 Kotlin 语言中可用的不同修饰符。访问修饰符用于限制应用程序中使用的变量、方法和类的使用。与其他 OOP 编程语言一样,此修饰符适用于多个位置,例如类头或方法声明中。Kotlin 中有四种可用的访问修饰符。

私人的

类、方法和包可以使用 private 修饰符来声明。一旦任何东西被声明为私有,那么它就可以在其直接范围内访问。例如,可以在该特定文件中访问私有包。私有类或接口只能由其数据成员等访问。

private class privateExample {
   private val i = 1
   private val doSomething() {
   }
}

在上面的示例中,类“privateExample”和变量 i 都只能在同一个 Kotlin 文件中访问,其中提到它们都在声明块中声明为私有。

受保护

Protected 是 Kotlin 的另一个访问修饰符,目前不可用于顶级声明,就像任何包都无法受到保护一样。受保护的类或接口仅对其子类可见。

class A() {
   protected val i = 1
}
class B : A() {
   fun getValue() : Int {
      return i
   }
}

在上面的例子中,变量“i”被声明为受保护的,因此,它仅对其子类可见。

内部的

Internal 是 Kotlin 中新引入的修饰符。如果任何内容被标记为内部,则该特定字段将位于内部字段中。内部包仅在其实现所在的模块内部可见。内部类接口仅对同一包或模块中存在的其他类可见。在下面的示例中,我们将看到如何实现内部方法。

class internalExample {
   internal val i = 1
   internal fun doSomething() {
   }
}

在上面的示例中,名为“doSomething”的方法和变量被称为内部变量,因此,这两个字段只能在声明它的包内访问。

民众

可以从项目工作区中的任何位置访问公共修改器。如果未指定访问修饰符,则默认情况下它将位于公共范围内。在我们之前的所有示例中,我们没有提到任何修饰符,因此,它们都在公共范围内。以下是一个示例,可帮助您了解有关如何声明公共变量或方法的更多信息。

class publicExample {
   val i = 1
   fun doSomething() {
   }
}

在上面的例子中,我们没有提到任何修饰符,因此所有这些方法和变量默认都是公共的。

Kotlin - 扩展

在本章中,我们将了解 Kotlin 的另一个新特性“扩展”。使用扩展,我们将能够添加或删除某些方法功能,甚至无需继承或修改它们。扩展以统计方式解决。它实际上并没有修改现有的类,而是创建了一个可以通过点操作调用的可调用函数。

功能扩展

在函数扩展中,Kotlin 允许在主类之外定义方法。在下面的示例中,我们将看到扩展是如何在功能级别实现的。

现场演示
class Alien {
   var skills : String = "null"
	
   fun printMySkills() {
      print(skills)
   }		
}
fun main(args: Array<String>) {
   var  a1 = Alien()
   a1.skills = "JAVA"
   //a1.printMySkills()
	
   var  a2 = Alien()
   a2.skills = "SQL"
   //a2.printMySkills()
	
   var  a3 = Alien()
   a3.skills = a1.addMySkills(a2)
   a3.printMySkills()
}
fun Alien.addMySkills(a:Alien):String{
   var a4 = Alien()
   a4.skills = this.skills + " " +a.skills
   return a4.skills
}

在上面的例子中,我们在“Alien”类中没有任何名为“addMySkills()”的方法,但是,我们仍然在类之外的其他地方实现相同的方法,这就是扩展的魔力。

上面的代码将在浏览器中生成以下输出。

JAVA SQL

对象扩展

Kotlin 提供了另一种机制来实现 Java 的静态功能。这可以使用关键字“伴随对象”来实现。使用这种机制,我们可以在工厂方法中创建类的对象,然后我们可以使用类名的引用来调用该方法。在下面的示例中,我们将创建一个“伴生对象”。

现场演示
fun main(args: Array<String>) {
   println("Heyyy!!!"+A.show())
}
class A {
   companion object {
      fun show():String {
         return("You are learning Kotlin from TutorialsPoint.com")
      }
   }
}

上面的代码将在浏览器中产生以下输出。

Heyyy!!! You are learning Kotlin from TutorialsPoint.com

上面的示例在 Java 中看起来像是静态的,但是,我们实时创建一个对象作为同一类的成员变量。这就是为什么它也包含在扩展属性下,并且可以称为对象扩展。您基本上是在扩展同一类的对象以使用某些成员函数。

Kotlin - 数据类

在本章中,我们将更多地了解 Kotlin 编程语言的数据类。每当一个类被标记为“数据”时,它就可以被标记为数据类。这种类型的类可用于分隔基本数据。除此之外,它不提供任何其他功能。

所有数据类都需要有一个主构造函数,并且所有主构造函数都应至少有一个参数。每当一个类被标记为数据时,我们就可以使用该数据类的一些内置函数,例如“toString()”、“hashCode()”等。任何数据类都不能有像abstract、open或internal这样的修饰符。数据类也可以扩展到其他类。在下面的示例中,我们将创建一个数据类。

现场演示
fun main(args: Array<String>) {
   val book: Book = Book("Kotlin", "TutorialPoint.com", 5)
   println("Name of the Book is--"+book.name) // "Kotlin"
   println("Puclisher Name--"+book.publisher) // "TutorialPoint.com"
   println("Review of the book is--"+book.reviewScore) // 5
   book.reviewScore = 7
   println("Printing all the info all together--"+book.toString()) 
   //using inbuilt function of the data class 
   
   println("Example of the hashCode function--"+book.hashCode())
}

data class Book(val name: String, val publisher: String, var reviewScore: Int)

上面的代码将在浏览器中产生以下输出,我们在其中创建了一个数据类来保存一些数据,并且从 main 函数中我们访问了它的所有数据成员。

Name of the Book is--"Kotlin"
Puclisher Name--"TutorialPoint.com"
Review of the book is--5
Printing all the info all together--(name-Kotlin, publisher-TutorialPoint.com, reviewScore-7)
Example of the hashCode function---1753517245

Kotlin - 密封类

在本章中,我们将了解另一种类类型,称为“密封”类。这种类型的类用于表示受限的类层次结构。Sealed 允许开发人员维护预定义类型的数据类型。要创建密封类,我们需要使用关键字“sealed”作为该类的修饰符。密封类可以有自己的子类,但所有这些子类都需要与密封类一起在同一个 Kotlin 文件中声明。在下面的示例中,我们将看到如何使用密封类。

现场演示
sealed class MyExample {
   class OP1 : MyExample() // MyExmaple class can be of two types only
   class OP2 : MyExample()
}
fun main(args: Array<String>) {
   val obj: MyExample = MyExample.OP2() 
   
   val output = when (obj) { // defining the object of the class depending on the inuputs 
      is MyExample.OP1 -> "Option One has been chosen"
      is MyExample.OP2 -> "option Two has been chosen"
   }
   
   println(output)
}

在上面的示例中,我们有一个名为“MyExample”的密封类,它只能有两种类型 - 一种是“OP1”,另一种是“OP2”。在主类中,我们在类中创建一个对象并在运行时分配其类型。现在,随着“MyExample”类被密封,我们可以在运行时应用“when”子句来实现最终输出。

在密封类中,我们不需要使用任何不必要的“else”语句来复杂化代码。上面的代码将在浏览器中产生以下输出。

option Two has been chosen

Kotlin - 泛型

与 Java 一样,Kotlin 提供了更高阶的变量类型,称为泛型。在本章中,我们将学习 Kotlin 如何实现泛型,以及作为开发人员如何使用泛型库中提供的这些功能。在实现方面,泛型与 Java 非常相似,但 Kotlin 开发人员引入了两个新关键字“out”“in”,以使 Kotlin 代码对开发人员来说更具可读性和易用性。

在 Kotlin 中,类和类型是完全不同的概念。根据示例,List 是 Kotlin 中的类,而 List<String> 是 Kotlin 中的类型。以下示例描述了如何在 Kotlin 中实现泛型。

fun main(args: Array<String>) {
   val integer: Int = 1
   val number: Number = integer
   print(number)
}

在上面的代码中,我们声明了一个“整数”,然后我们将该变量分配给一个数字变量。这是可能的,因为“Int”是 Number 类的子类,因此类型转换在运行时自动发生并产生输出“1”。

让我们进一步了解 Kotlin 中的泛型。每当我们不确定要在应用程序中使用的数据类型时,最好选择通用数据类型。一般来说,Kotlin 中的泛型由<T>定义,其中“T”代表模板,可以由 Kotlin 编译器动态确定。在下面的示例中,我们将了解如何在 Kotlin 编程语言中使用通用数据类型。

现场演示
fun main(args: Array<String>) {
   var objet = genericsExample<String>("JAVA")
   var objet1 = genericsExample<Int>(10)
}
class genericsExample<T>(input:T) {
   init {
      println("I am getting called with the value "+input)
   }
}

在上面的代码中,我们创建了一个具有通用返回类型的类,该类表示为<T>。看一下 main 方法,我们在运行时通过证明值类型动态定义了它的值,同时创建了此类的对象。这就是 Kotlin 编译器解释泛型的方式。一旦我们在编码环境中运行此代码,我们将在浏览器中获得以下输出。

I am getting called with the value JAVA
I am getting called with the value 10

当我们想要将泛型类型分配给它的任何超类型时,我们需要使用“out”关键字,而当我们想要将泛型类型分配给它的任何子类型时,我们需要使用“in”关键词。在下面的示例中,我们将使用“out”关键字。同样,您可以尝试使用“in”关键字。

现场演示
fun main(args: Array<String>) {
   var objet1 = genericsExample<Int>(10)
   var object2 = genericsExample<Double>(10.00)
   println(objet1)
   println(object2)
}
class genericsExample<out T>(input:T) {
   init {
      println("I am getting called with the value "+input)
   }
}

上面的代码将在浏览器中产生以下输出。

I am getting called with the value 10
I am getting called with the value 10.0
genericsExample@28d93b30
genericsExample@1b6d3586

Kotlin - 委托

Kotlin通过引入新的关键字“by”来支持“委托”设计模式。使用此关键字或委托方法,Kotlin 允许派生类通过特定对象访问接口的所有已实现的公共方法。以下示例演示了 Kotlin 中如何发生这种情况。

现场演示
interface Base {
   fun printMe() //abstract method
}
class BaseImpl(val x: Int) : Base {
   override fun printMe() { println(x) }   //implementation of the method
}
class Derived(b: Base) : Base by b  // delegating the public method on the object b

fun main(args: Array<String>) {
   val b = BaseImpl(10)
   Derived(b).printMe() // prints 10 :: accessing the printMe() method 
}

在示例中,我们有一个接口“Base”,其抽象方法名为“printme()”。在 BaseImpl 类中,我们正在实现这个“printme()”,稍后我们在另一个类中使用“by”关键字来使用这个实现。

上面的代码将在浏览器中产生以下输出。

10

财产委托

在上一节中,我们学习了使用“by”关键字的委托设计模式。在本节中,我们将学习使用 Kotlin 库中提到的一些标准方法来委托属性。

委托意味着将责任传递给另一个类或方法。当属性已经在某些地方声明时,我们应该重用相同的代码来初始化它们。在下面的示例中,我们将使用 Kotlin 提供的一些标准委托方法和一些标准库函数来实现委托。

使用 Lazy()

Lazy 是一个 lambda 函数,它接受一个属性作为输入,并返回一个Lazy<T>实例,其中 <T> 基本上是它所使用的属性的类型。让我们看一下下面的内容来了解​​它是如何工作的。

现场演示
val myVar: String by lazy {
   "Hello"
}
fun main(args: Array<String>) {
   println(myVar +" My dear friend")
}

在上面的代码中,我们将变量“myVar”传递给 Lazy 函数,该函数反过来将值分配给其对象,并将相同的值返回给主函数。以下是浏览器中的输出。

Hello My dear friend

委托.Observable()

Observable() 使用两个参数来初始化对象并将其返回给被调用的函数。在下面的示例中,我们将看到如何使用 Observable() 方法来实现委托。

现场演示
import kotlin.properties.Delegates
class User {
   var name: String by Delegates.observable("Welcome to Tutorialspoint.com") {
      prop, old, new ->
      println("$old -> $new")
   }
}
fun main(args: Array<String>) {
   val user = User()
   user.name = "first"
   user.name = "second"
}

上面的代码将在浏览器中产生以下输出。

first -> second

一般来说,语法就是“by”关键字被委托后的表达式。变量p的get ()set()方法将被委托给Delegate 类中定义的getValue()setValue()方法。

class Example {
   var p: String by Delegate()
}

对于上面的代码,以下是我们需要生成的委托类,以便为变量p赋值。

class Delegate {
   operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
      return "$thisRef, thank you for delegating '${property.name}' to me!"
   }
   operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
      println("$value has been assigned to '${property.name} in $thisRef.'")
   }
}

读取时,将调用 getValue() 方法;设置变量时,将调用 setValue() 方法。

Kotlin - 函数

Kotlin 是一种静态类型语言,因此函数在其中发挥着重要作用。我们对函数非常熟悉,因为我们在整个示例中都使用函数。函数用关键字“fun”声明。与任何其他 OOP 一样,它也需要返回类型和选项参数列表。

在下面的示例中,我们定义一个名为 MyFunction 的函数,并从主函数中调用该函数并传递一些参数。

现场演示
fun main(args: Array<String>) {
   println(MyFunction("tutorialsPoint.com"))
}
fun MyFunction(x: String): String {
   var c:String  = "Hey!! Welcome To ---"
   return (c+x)
}

上面的代码将在浏览器中产生以下输出。

Hey!! Welcome To ---tutorialsPoint.com

该函数应声明如下 -

fun <nameOfFunction>(<argument>:<argumentType>):<ReturnType>

以下是 Kotlin 中可用的一些不同类型的函数。

拉姆达函数

Lambda 是一个高级函数,可以在声明函数并定义函数时大大减少样板代码。Kotlin 允许您定义自己的 lambda。在 Kotlin 中,您可以声明 lambda 并将该 lambda 传递给函数。

看一下下面的例子。

现场演示
fun main(args: Array<String>) {
   val mylambda :(String)->Unit  = {s:String->print(s)}
   val v:String = "TutorialsPoint.com"
   mylambda(v)
}

在上面的代码中,我们创建了自己的 lambda,称为“mylambda”,并向该 lambda 传递了一个变量,该变量是 String 类型,包含值“TutorialsPoint.com”。

上面的代码将在浏览器中产生以下输出。

TutorialsPoint.com

内联函数

上面的示例展示了我们可以在 Kotlin 应用程序中使用的 lambda 表达式的基础知识。现在,我们可以将 lambda 传递给另一个函数来获取输出,这使得调用函数成为内联函数。

看一下下面的例子。

现场演示
fun main(args: Array<String>) {
   val mylambda:(String)->Unit  = {s:String->print(s)}
   val v:String = "TutorialsPoint.com"
   myFun(v,mylambda) //passing lambda as a parameter of another function 
}
fun myFun(a :String, action: (String)->Unit) { //passing lambda 
   print("Heyyy!!!")
   action(a)// call to lambda function
}

上面的代码将在浏览器中产生以下输出。使用内联函数,我们传递了一个 lambda 作为参数。任何其他函数都可以使用“inline”关键字成为内联函数。

Heyyy!!!TutorialsPoint.com

Kotlin - 解构声明

Kotlin 包含其他编程语言的许多功能。它允许您一次声明多个变量。这种技术称为解构声明。

以下是解构声明的基本语法。

val (name, age) = person

在上面的语法中,我们创建了一个对象并在一条语句中将所有它们一起定义。稍后我们可以按如下方式使用它们。

println(name)
println(age)

现在,让我们看看如何在实际应用程序中使用它。考虑以下示例,其中我们创建一个具有某些属性的 Student 类,稍后我们将使用它们来打印对象值。

现场演示
fun main(args: Array<String>) {
   val s = Student("TutorialsPoint.com","Kotlin")
   val (name,subject) = s
   println("You are learning "+subject+" from "+name)
}
data class Student( val a :String,val b: String ){
   var name:String = a
   var subject:String = b
}

上面的代码将在浏览器中产生以下输出。

You are learning Kotlin from TutorialsPoint.com

Kotlin - 异常处理

异常处理是编程语言非常重要的一部分。这项技术限制我们的应用程序在运行时生成错误的输出。在本章中,我们将学习如何在 Kotlin 中处理运行时异常。Kotlin 中的异常与 Java 中的异常非常相似。所有异常都是“Throwable”类的后代。以下示例展示了如何在 Kotlin 中使用异常处理技术。

fun main(args: Array<String>) {
   try {
      val myVar:Int = 12;
      val v:String = "Tutorialspoint.com";
      v.toInt();
   } catch(e:Exception) {
      e.printStackTrace();
   } finally {
      println("Exception Handeling in Kotlin");
   }
}

在上面的代码中,我们声明了一个字符串,然后将该字符串绑定到整数中,这实际上是一个运行时异常。因此,我们将在浏览器中得到以下输出。

val myVar:Int = 12;
Exception Handeling in Kotlin

注意- 与 Java 一样,Kotlin 也会在执行 catch 块后执行 finally 块。