Kotlin classes and objects
Class definition
Kotlin
classes can contain constructors and initialization code blocks, functions, attributes, inner classes, and object declarations.
Kotlin
use keywords in class
declare the class, followed by the class name:
class Runoob { // Class name is Runoob
// Within the braces are class body constructions
}
We can also define an empty class:
class Empty
You can define member functions in a class:
class Runoob() {
fun foo() { print("Foo") } // member function
}
Properties of the class
Attribute definition
The properties of the class can use the keyword var
declared as mutable, otherwise use read-only keywords val
declared immutable.
class Runoob {
var name: String = ……
var url: String = ……
var city: String = ……
}
We can use the constructor to create an instance of the class as we would with a normal function:
val site = Runoob() // There is no new keyword in Kotlin
To use an attribute, simply refer to it by name
site.name // Use Number to reference
site.url
Kotlin
class in can have a primary constructor, as well as one or moresecondary constructors, which are part of the class header, after the classname:
class Person constructor(firstName: String) {}
If the main constructor does not have any comments and no visibility modifiers, then constructor
keywords can be omitted.
class Person(firstName: String) {
}
Getter and setter
The complete syntax of the property declaration:
var <propertyName>[: <PropertyType>] [= <property_initializer>]
[<getter>]
[<setter>]
getter
and setter
are all optional.
If the attribute type can be inferred from the initialization statement or the member function of the class, the type can be omitted val
setting is not allowed setter
function because it is read-only.
var allByDefault: Int? // Error: requires an initialization statement,
default implementation of getter and setter methods
var initialized = 1 // Type is Int, default implementation of getters and setters
val simple: Int? // Type is Int, default implementation getter,
but must be initialized in the constructor
val inferredType = 1 // The type is Int, and the default implementation is getter
Example
The following example defines a Person
class that contains two variable variables, lastName
and no
. lastName
modifies the ‘getter’ methoand no
modifies the setter
method
class Person {
var lastName: String = "zhang"
get() = field.toUpperCase() // Convert variables to uppercase after assignment
set
var no: Int = 100
get() = field // Backend variable
set(value) {
if (value < 10) { // If the passed in value is less than 10,
return this value
field = value
} else {
field = -1 // If the value passed in is greater
than or equal to 10, return -1
}
}
var heiht: Float = 145.4f
private set
}
// test
fun main(args: Array<String>) {
var person: Person = Person()
person.lastName = "wang"
println("lastName:${person.lastName}")
person.no = 9
println("no:${person.no}")
person.no = 20
println("no:${person.no}")
}
The output is as follows:
lastName:WANG
no:9
no:-1
Kotlin
class cannot have fields in. Provide Backing Fields
(back-end variable) mechanism, alternate field use field
keyword declaration field
keywords can only be used for accessors of properties, such as the example above:
var no: Int = 100
get() = field // Backend variable
set(value) {
if (value < 10) { // If the passed in value is less than 10, return this value
field = value
} else {
field = -1 // If the value passed in is greater than or equal to 10, return -1
}
}
Non-empty properties must be initialized at the time of definition kotlin
provides a scheme that can delay initialization, using the lateinit
keyword description properties:
public class MyTest {
lateinit var subject: TestSubject
@SetUp fun setup() {
subject = TestSubject()
}
@Test fun test() {
subject.method() // dereference directly
}
}
Main constructor
The main constructor cannot contain any code, the initialization code can beplaced in the initialization code segment, and the initialization code snippet can be used init
keyword as a prefix.
class Person constructor(firstName: String) {
init {
println("FirstName is $firstName")
}
}
Note: the parameters of the main constructor can be used in the initialization code snippet or in the property initialization code defined by the class body n. A concise syntax that uses the main constructor to define properties and initialize property values (which can be var
or val
):
class People(val firstName: String, val lastName: String) {
//...
}
If the constructor has comments or visibility modifiers, then constructor
keyword is required, and comments and modifiers should be placed before it.
Example
Create a Runoob
class and pass in the site name through the constructor:
class Runoob constructor(name: String) { // Class name is Runoob
// Within the braces are class body constructions
var url: String = "http://www.runoob.com"
var country: String = "CN"
var siteName = name
init {
println("Initialize website name: ${name}")
}
fun printTest() {
println("I am a function of a class")
}
}
fun main(args: Array<String>) {
val runoob = Runoob("Novice Tutorial")
println(runoob.siteName)
println(runoob.url)
println(runoob.country)
runoob.printTest()
}
The output is as follows:
Initialize website name: Novice Tutorial
Novice Tutorial
http://www.runoob.com
CN
I am a function of a class
Secondary constructor
Class can also have a secondary constructor that needs to be prefixed constructor
:
class Person {
constructor(parent: Person) {
parent.children.add(this)
}
}
If the class has a primary constructor, each secondary constructor will represent the primary constructor, either directly or indirectly through another secondary constructor. To proxy another constructor in the same class to use the this
keywords:
class Person(val name: String) {
constructor (name: String, age:Int) : this(name) {
// initialization...
}
}
If a non-abstract class does not declare a constructor (primary or secondaryconstructor), it produces a constructor with no arguments. The constructor is public
. If you don’t want your class to have a public constructor, you have to declare an empty main constructor:
class DontCreateMe private constructor () {
}
Note: in JVM
the virtual machine, if all parameters of the main constructor have default values, the compiler generates an additional no-parameter constructor, which directly uses the default value. This makes it possible Kotlin
. It can be easier to use things like Jackson
or JPA
uses a no-parameter constructor to create a library of class instances.
class Customer(val customerName: String = "")
Example
class Runoob constructor(name: String) { // Class name is Runoob
// Within the braces are class body constructions
var url: String = "http://www.runoob.com"
var country: String = "CN"
var siteName = name
init {
println("Initialize website name: ${name}")
}
// Secondary constructor
constructor (name: String, alexa: Int) : this(name) {
println("Alexa ranking $alexa")
}
fun printTest() {
println("I am a function of a class")
}
}
fun main(args: Array<String>) {
val runoob = Runoob("Novice Tutorial", 10000)
println(runoob.siteName)
println(runoob.url)
println(runoob.country)
runoob.printTest()
}
The output is as follows:
Initialize website name: Novice Tutorial
Alexa Ranked 10000
Novice Tutorial
http://www.runoob.com
CN
I am a function of a class
Abstract class
Abstraction is one of the characteristics of object-oriented programming. The class itself, or some members of the class, can be declared as abstract
. There is no concrete implementation of abstract members in the class.
Note: there is no need to label abstract classes or abstract members open
notes.
open class Base {
open fun f() {}
}
abstract class Derived : Base() {
override abstract fun f()
}
Nested class
We can nest classes in other classes and look at the following examples:
class Outer { // External Class
private val bar: Int = 1
class Nested { // Nested classes
fun foo() = 2
}
}
fun main(args: Array<String>) {
val demo = Outer.Nested().foo() // Call Format: External Class,
Nested Class, Nested Class Method/Attribute
println(demo) // == 2
}
Inner class
Inner class usage inner
keyword to represent.
The inner class has a reference to the object of the external class, so the inner class can access the external class member properties and member functions.
class Outer {
private val bar: Int = 1
var v = "Member Properties"
/**Nested Inner Class**/
inner class Inner {
fun foo() = bar // Accessing External Class Members
fun innerTest() {
var o = this@Outer //Get member variables of external classes
println("Internal classes can refer to members of external classes, such as:" + o.v)
}
}
}
fun main(args: Array<String>) {
val demo = Outer().Inner().foo()
println(demo) // 1
val demo2 = Outer().Inner().innerTest()
println(demo2) // Internal classes can refer to members of external classes,
such as member properties
}
To disambiguate, access the this
we use the this@label
, of which @label
it’s a reference, this
Label of the source.
Anonymous inner class
Use object expressions to create anonymous inner classes:
class Test {
var v = "Member Properties"
fun setInterFace(test: TestInterFace) {
test.test()
}
}
/**
* Define interfaces
*/
interface TestInterFace {
fun test()
}
fun main(args: Array<String>) {
var test = Test()
/**
* Using object expressions to create interface objects, that is,
instances of anonymous inner classes.
*/
test.setInterFace(object : TestInterFace {
override fun test() {
println("Object expression creates an instance of an anonymous inner class")
}
})
}
Class modifier
Class modifiers include classModifier
and accessModifier
:
classModifier
class property modifiers that indicate the characteristicsof the class itself.
abstract//Abstract class
final//Class is not inheritable, default attribute
enum//Enumeration class
open//Class inheritable, class defaults to final
annotation//Annotation class
accessModifier
: Access modifier
private//visible only in the same file
protected//Visible in the same file or subclass
public//Visible everywhere called
internal//Visible within the same module
Example
// file name:example.kt
package foo
private fun foo() {} // Visible within example.kt
public var bar: Int = 5 // This attribute is visible everywhere
internal val baz = 6 // Visible within the same module