kotlin 类构造函数
In this tutorial, we’ll be discussing the Object Oriented Programming concepts of Kotlin. We’ll discuss Kotlin Class in detail. We will also look at kotlin constructors, access modifiers and abstract class.
在本教程中,我们将讨论Kotlin的面向对象编程概念。 我们将详细讨论Kotlin课堂。 我们还将研究kotlin构造函数,访问修饰符和抽象类。
A class is a blue print defined which groups functions and properties. Classes in Kotlin are defined using the keyword class
followed by the class name. The body goes inside the curly braces.
类是定义功能和属性的蓝图。 Kotlin中的类是使用关键字class
和类名定义的。 身体进入花括号内。
class FirstClass {
}
An instance of the class is instantiated in the following way:
该类的实例通过以下方式实例化:
val firstClass = FirstClass()
var new = FirstClass() //here new is the name of the var.
Contrary to Java, new
isn’t a keyword in Kotlin.
与Java相反, new
不是Kotlin中的关键字。
Classes by default are final in Kotlin.
So the equivalent of the above definitions in Java would like something like this:
默认情况下,类是Kotlin中的final 。
因此,Java中与上述定义等效的东西是这样的:
public final class FirstClass {
}
Hence, by default classes in Kotlin are not inheritable.
因此,默认情况下,Kotlin中的类是不可继承的。
To make a class non-final we need to append the keyword open
.
为了使一个类不最终,我们需要附加关键字open
。
open class Me{
}
The open
annotation allows others to inherit from this class.
open
注释允许其他人从此类继承。
Let’s create a class with a few functions and a property. We’ll see how to access the functions and properties of that class. Furthermore, we’ll see how to set the member properties.
让我们创建一个带有一些函数和一个属性的类。 我们将看到如何访问该类的函数和属性。 此外,我们将看到如何设置成员属性。
class User {
var loggedIn: Boolean = false
val cantChangeValue = "Hi"
fun logOn() {
loggedIn = true
}
fun logOff() {
loggedIn = false
}
}
fun main(args: Array) {
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.
}
The function main
belongs to the Test.kt
class. To access members and functions, we need to use the dot operator. A val
property can’t be set again using a dot operator.
函数main
属于Test.kt
类。 要访问成员和函数,我们需要使用点运算符。 不能使用点运算符再次设置val
属性。
Kotlin init block is defined as shown below.
Kotlin初始化块的定义如下所示。
class User {
init{
print("Class instance is initialised.")
}
var loggedIn: Boolean = false
val cantChangeValue = "Hi"
fun logOn() {
loggedIn = true
}
fun logOff() {
loggedIn = false
}
}
The code inside the init
block is the first to be executed when the class is instantiated. The init
block is run every time the class is instantiated, with any kind of constructor as we shall see next.
当实例化该类时, init
块中的代码是第一个要执行的代码。 每次实例化该类时,都会使用任何类型的构造函数运行init
块,接下来将要看到。
Multiple initializer blocks can be written in a class. They’ll be executed sequentially as shown below.
可以在一个类中写入多个初始化程序块。 它们将按顺序执行,如下所示。
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) {
var multiInit = MultiInit("Kotlin")
}
//Following is printed in the log console.
//First initializer block that prints Kotlin
//Second initializer block that prints 6
Kotlin classes allow printing properties in the declaration itself by using the also
function as shown below.
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) {
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 Constructors are special member functions that are used to initialize properties. Constructors in Kotlin are written and structured differently compared with Java. By default a class has an empty constructor as shown below:
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) {
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
Primary Constructors in Kotlin are defined in the class header itself as shown below.
Kotlin中的主要构造函数在类标题本身中定义,如下所示。
class User(var name: String, var isAdmin: Boolean) {
init {
name = name + " @ JournalDev.com"
println("Author Name is $name. Is Admin? $isAdmin")
}
}
The primary constructors definition goes inside the class header. We’ve defined the property types(val/var) in the constructor itself.
主要的构造函数定义在类头中。 我们已经在构造函数中定义了属性类型(val / var)。
Note: Unless stated as a var
, by default, constructor arguments are val
.
注意:除非声明为var
,否则默认情况下,构造函数参数为val
。
class User(name: String, isAdmin: Boolean)
In the above code, both name and isAdmin can’t be reassigned.
在上面的代码中,name和isAdmin都无法重新分配。
Alternatively, we can aslo assign the constructor arguments to the member properties in the class as shown below.
或者,我们也可以将构造函数参数分配给类中的成员属性,如下所示。
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) {
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 allows us to specify default values in the constructor itself as shown below.
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) {
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
Secondary Constructors are written inside the body of the class by prefixing with the keyword constructor
. Following example demonstrates the same.
辅助构造函数通过在关键字的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) {
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.
如果该类包含一个主构造函数,则辅助构造函数必须在其声明中引用它。 声明是使用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
block is used to initialise the member property skill
. The secondary constructor delegates to the primary constructor using : this
.
init
块用于初始化成员属性skill
。 次要构造函数使用: this
委托给主要构造函数: this
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.
到目前为止,我们已经使用类实例上的点运算符访问和修改了类中的属性。 让我们使用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) {
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.
设置器中的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) {
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.
capitalize()
将字符串的第一个字母大写。
Note: if the property is a val
, set
method won’t compile.
注意 :如果属性是val
,则set
方法将无法编译。
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.
可见性修饰符也适用于构造函数。 为主要构造函数分配修饰符需要我们在类标题中的构造constructor
旁边指定关键字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) {
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.
私有构造函数不能在类外部调用。 在上面的代码中,我们只能使用辅助构造函数在另一个函数中实例化该类。
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.
像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) {
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.
注意 :抽象类默认情况下是open
。 因此,不需要添加open修饰符以允许子类化。
override
keyword is used to override a method in the subclass.
override
关键字用于覆盖子类中的方法。
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.
在本教程中,我们已经介绍了kotlin类的基础知识。 还有更多的东西,例如数据类,密封类,继承等。我们将在接下来的教程中介绍它们。
References : Kotlin Docs
参考文献: Kotlin Docs
翻译自: https://www.journaldev.com/18491/kotlin-class-constructor
kotlin 类构造函数