


Chapter 4 Class and Object-Oriented Programming Chapter 4 Class and Object-Oriented Programming
Chapter 4 Class and Object Oriented Programming
In the previous chapters, we learned about Kotlin's basic language knowledge, type system and other related knowledge. In this chapter and the next chapter, we will learn Kotlin's support for object-oriented programming and functional programming.
In this chapter, we introduce Kotlin's object-oriented programming.
4.1 A brief history of object-oriented programmingIn the late 1950s, when writing large programs in the FORTRAN language, since there was no encapsulation mechanism, the variables at that time were all "global variables", so variable name conflicts would inevitably occur frequently. In ALGOL60, a program block identified by Begin - End is used to make the variable names in the block be local to avoid them from conflicting with variables with the same name outside the block in the program. For the first time in programming languages, the mechanism of encapsulation (protection) is provided. Since then, program block structure has been widely used in high-level languages such as Pascal, Ada, and C.
In the mid-to-late 1960s, Simula language was developed based on ALGOL. It developed the concept of ALGOL's block structure one step forward, proposed the concept of object, and used classes, which also supported class inheritance. A brief history of subsequent developments is shown in the figure below:

A brief history of object-oriented development
Alan Kay is one of the inventors of Smalltalk's object-oriented programming language and one of the founders of object-oriented programming ideas. He is also the earliest conceiver of laptops and an architect of modern Windows GUIs. Aaron Kay was the first to propose the concept of PC and the Internet, so people respectfully called him the "Master of Prophecy". He is one of the few technical geniuses in the IT industry today.
Object-oriented programming ideas are mainly reusability and flexibility (elasticity). Reusability is a major mechanism of object-oriented programming. Flexibility is mainly a characteristic of responding to changes, because customer needs are constantly changing. How to adapt to changes in customer needs is a problem of software design flexibility or flexibility.
Java is an object-oriented programming language, based on Smalltalk language, as an OOP language, it has the following five basic features:
1. Everything is an object, and each object stores data and can perform operations on itself. Therefore, each object contains two parts: member variables and member methods. The value of a member variable can be changed in a member method.
2. Programs are collections of objects. They inform each other of what they want to do by sending messages, that is, calling the corresponding member functions.
3. Each object has its own storage composed of other objects, which means that when creating a new object, you can use existing objects in member variables.
4. Each object has its type, and each object is an instance of a certain class. The characteristic that distinguishes each class from other classes is what type of message it can send, that is, which member functions it defines.
5. All objects of a certain type can accept the same message. Another description of an object is that the object has state (data, member variables), behavior (operation, member method) and identity (member name, memory address).
Object-oriented language is actually an abstraction of real objects in real life.
The requests (messages) that each object can accept are defined by the object's interface, and in the program, it must be composed of code that satisfies these requests, which is called the implementation of this interface. When sending a message (request) to an object, the object knows the purpose of the message (the implementation of the method is defined) and then executes the corresponding code.
We often say that some code snippets are elegant or beautiful, which actually means that they are more easily processed by human limited thinking.
For program compounding, a good code is that its surface area grows slowly than its volume.
The "surface area" of a code block is the information we need when we compound the code block (definition of the interface API protocol). The "volume" of the code block is the implementation logic inside the interface (the implementation code behind the API).
In object-oriented programming, an ideal object should only expose its abstract interface (pure surface, no volume), and its method plays the role of arrows. If you want to understand how one object reconciles with other objects, when you find that you have to dig deep into the implementation of the object, the original advantages of the programming paradigm you are using will disappear.
Object-oriented programming is a programming idea. Compared with early structured programming, the abstraction level is higher, and the way of thinking and solving problems is closer to the human way of thinking. Modern programming languages basically support object-oriented programming paradigm.
All problems in the computer field can be solved by abstract encapsulation to the upper layer. The essential concept of encapsulation here is actually "mapping". From process-oriented to object-oriented, to design patterns, architectural design, service-oriented, Sass/Pass/Iass, etc., there are many different ideas for software theory, but they will never leave their roots.
What kind of problem do you want to solve? What is your problem area? What is your model (data structure)? What is your algorithm? What is your understanding of the essence of this world? What are the logical problems in your business area, what are the processes? etc.Object-oriented programming thinks about things (objects) in the real world as the center, understands problems, and abstracts them into classes in the system based on the essential characteristics of these things. Its core idea can be briefly explained in the figure below:

Object-Oriented Programming
Object-oriented programming is based on class programming and is closer to human habitual methods of solving problems. Make the software world more like the real world. Object-oriented programming decomposes the system by abstracting key problem domains. Objects can not only represent concrete things, but also abstract rules, plans or events. The core concepts of object-oriented programming are shown in the following figure

The core concept of object-oriented programming
4.2 Declaration ClassThis section introduces the declarations of classes and constructors in Kotlin.
4.2.1 Empty ClassUse the class keyword to declare the class. We can declare a class that does nothing
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">class AnEmptyClassfun main(args: Array<String> ) { val anEmptyClass = AnEmptyClass() // Kotlin中不需要使用new println(anEmptyClass) println(anEmptyClass is AnEmptyClass) // 对象实例是AnEmptyClass类型println(anEmptyClass::class)}</code>
Output
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">com.easy.kotlin.AnEmptyClass@2626b418trueclass com.easy.kotlin.AnEmptyClass (Kotlin reflection is not available)</code>4.2.2 Declare classes and constructors
In Kotlin, we can declare the constructor at the same time when declaring the class. The syntax format is to use brackets to include the parameter list of the constructor after the class.
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">class Person(var name: String, var age: Int, var sex: String) { // 声明类和构造函数override fun toString(): String { // override关键字,重写toString() return "Person(name='$name', age=$age, sex='$sex')" }}</code>
Using such a concise syntax, the attribute can be defined and the attribute value can be initialized through the main constructor (the attribute value can be var or val).
Use Person class in code like this
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">val person = Person("Jack", 29, "M")println("person = ${person}")</code>
Output
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">person = Person(name='Jack', age=29, sex='M')</code>
In addition, we can declare the attribute first, and then initialize the attribute value when constructing the instance object. Then our Person class can be declared as follows
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">class Person1 { lateinit var name: String // lateinit 关键字表示该属性延迟初始化var age: Int = 0 // lateinit 关键字不能修饰primitive 类型lateinit var sex: String override fun toString(): String { return "Person1(name='$name', age=$age, sex='$sex')" }}</code>
We can create a Person1 instance object in the code like this
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript"> val person1 = Person1() person1.name = "Jack" person1.age = 29 person1.sex = "M" println("person1 = ${person1}")</code>
Output
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">person1 = Person1(name='Jack', age=29, sex='M')</code>
If we want to declare a class with multiple constructor methods, we can declare the constructor function using the constructor keyword. The example code is as follows
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">class Person2() { // 无参的主构造函数lateinit var name: String var age: Int = 0 lateinit var sex: String constructor(name: String) : this() { // this 关键字指向当前类对象实例this.name = name } constructor(name: String, age: Int) : this(name) { this.name = name this.age = age } constructor(name: String, age: Int, sex: String) : this(name, age) { this.name = name this.age = age this.sex = sex } override fun toString(): String { return "Person1(name='$name', age=$age, sex='$sex')" }}</code>
Overall, there are some boilerplate codes. In fact, in IDEA, when we write the above code, we only need to write the following 3 lines, and the rest will be automatically generated by IDEA.
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">class Person2 { lateinit var name: String var age: Int = 0 lateinit var sex: String}</code>
Automatically generate constructor operation diagram
1. "Right-click" the mouse operation in the current class and select Generate (the shortcut key on the Mac is Command N)

Right-click the mouse operation
After clicking, the dialog box pops up: Generate secondary constructor
Select Generate
Select the constructor parameters
Generate secondary constructors
Select the corresponding attribute and click OK to generate it.
No attribute is selected, generate
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">constructor()</code>
Select a name attribute to generate
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript"> constructor(name: String) { this.name = name }</code>
Select name, age attribute generation
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript"> constructor(name: String, age: Int) : this(name) { this.name = name this.age = age }</code>
Select all 3 attributes to generate
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript"> constructor(name: String, age: Int, sex: String) : this(name, age) { this.name = name this.age = age this.sex = sex }</code>
Finally, we can create a Person2 instance object in the code like this
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript"> val person21 = Person2() person21.name = "Jack" person21.age = 29 person21.sex = "M" println("person21 = ${person21}") val person22 = Person2("Jack", 29) person22.sex = "M" println("person22 = ${person22}") val person23 = Person2("Jack", 29, "M") println("person23 = ${person23}")</code>
In fact, the constructor we use the most in programming practice is this
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">class Person(var name: String, var age: Int, var sex: String)</code>
When it is really necessary to build an object through more complex logic, it can be implemented using the Builder mode.
4.3 Abstract classes and interfacesAbstract classes represent the relationship of "is-a", while interfaces represent the relationship of "has-a".
Abstract classes are used to represent abstract concepts in problem areas. All programming languages provide abstract mechanisms. Machine language is an imitation abstract of machines, assembly language is a high-level abstraction of machine language, and high-level languages (Fortran, C, Basic, etc.) are a high-level abstraction of assembly. The object-oriented programming language we are talking about here is a high-level encapsulation of procedural functions. This process is shown in the figure below

Abstract mechanism of programming languages
Abstract classes and interfaces are two different abstract concepts in the Kotlin language, and their existence provides very good support for polymorphism. This mechanism is the same as Java.
4.3.1 Abstract classes and abstract membersAbstraction is relative to concreteness. For example, designing a graphic editing software, there are specific concepts such as rectangle, circle, triangle, etc. in the problem area, and they are concrete. But they all belong to the abstract concept of shape (Shape). Their relationship is shown in the figure below

Abstract inheritance relationship of shape Shape
The corresponding Kotlin code is as follows
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">package com.easy.kotlinabstract class Shapeclass Rectangle : Shape() // 继承类的语法是使用冒号: , 父类需要在这里使用构造函数初始化class Circle : Shape()class Triangle : Shape()</code>
Because abstract concepts do not have corresponding specific concepts in the problem area, abstract classes cannot be instantiated. The following code compiler will report an error
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">val s = Shape() // 编译不通过!不能实例化抽象类</code>
We can only instantiate its inherited subclass. The code example is as follows
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">val r = Rectangle()println(r is Shape) // true</code>
Now we have abstract classes, but no members. Usually, members of a class have properties and functions. Members of abstract classes must also be abstract and need to be modified using the abstract keyword. Below we declare an abstract class Shape with width , heigth , radius attributes and area() function. The code is as follows
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">abstract class Shape { abstract var width: Double abstract var heigth: Double abstract var radius: Double abstract fun area(): Double}</code>
At this time, the method of inheriting the abstract class Shape is as follows
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">class Rectangle(override var width: Double, override var heigth: Double, override var radius: Double) : Shape() { // 声明类的同时也声明了构造函数override fun area(): Double { return heigth * width }}class Circle(override var width: Double, override var heigth: Double, override var radius: Double) : Shape() { override fun area(): Double { return 3.14 * radius * radius }}</code>
Among them, override is the keyword that overrides the parent class attributes and functions.
In the code, call the function of the specific implemented class
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">fun main(args: Array<String> ) { val r = Rectangle(3.0, 4.0, 0.0) println(r.area()) // 12.0 val c = Circle(0.0, 0.0, 4.0) println(c.area()) // 50.24}</code>
There can be functions with implementation in abstract classes. For example, we add a function onClick() to the abstract class Shape.
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">abstract class Shape { ... fun onClick() { // 默认是final的,不可被覆盖重写println("I am Clicked!") }}</code>
Then, we can directly call the onClick() function in all subclasses
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript"> val r = Rectangle(3.0, 4.0, 0.0) r.onClick() // I am Clicked! val c = Circle(0.0, 0.0, 4.0) c.onClick() // I am Clicked!</code>
The onClick() function in the parent class Shape is final by default and cannot be overridden and rewritten. If you want to open the function to reimplement the subclass, we can prefix it with the open keyword
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">abstract class Shape { ... open fun onClick() { println("I am Clicked!") }}</code>
Override override in subclasses
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">class Rectangle(override var width: Double, override var heigth: Double, override var radius: Double) : Shape() { override fun area(): Double { return heigth * width } override fun onClick(){ println("${this::class.simpleName} is Clicked!") }}fun main(args: Array<String> ) { val r = Rectangle(3.0, 4.0, 0.0) println(r.area()) r.onClick()}</code>
Among them, this::class.simpleName is the reflection API in Kotlin. In the build.gradle of the Gradle project, we need to add the dependency compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" , which we will introduce in detail in the following chapters.
The above code runs the output
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">12.0Rectangle is Clicked!</code>
When a child class inherits a certain class, member variables in the parent class can be used, but not all member variables of the parent class are fully inherited. The specific principles are as follows:
1. Can inherit public and protected member variables of the parent class; cannot inherit private member variables of the parent class;
2. For the package access permission member variable of the parent class, if the subclass and the parent class are in the same package, the subclass can be inherited; otherwise, the subclass cannot be inherited;
3. For parent class member variables that can be inherited by subclasses, if a member variable with the same name appears in the subclass, a hidden phenomenon will occur, that is, the member variables of the subclass will block the member variables of the parent class with the same name. If you want to access the member variable of the same name in the parent class in the subclass, you need to use the super keyword to reference it.
4.3.2 InterfaceAn interface is a "class" that is more abstract than an abstract class. The interface itself represents a concept of "type". But at the syntax level, an interface itself is not a class, and it cannot instantiate an interface, we can only instantiate its implementation class.
Interfaces are used to establish protocols between classes. The implementation class that implements this interface must implement all methods of the interface. In Java 8 and Kotlin, interfaces can implement some common methods.
Interfaces are extensions of abstract classes. Like Java, Kotlin does not support inheriting multiple parent classes at the same time, which means that inheritance can only have one parent class (single inheritance). However, interfaces are different. A class can implement multiple interfaces at the same time (multiple combinations), regardless of whether there is any relationship between these interfaces. This allows multiple inheritance to be achieved.
Similar to Java, Kotlin uses interface as the keyword for the interface:
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">interface ProjectService</code>
Kotlin's interface is similar to that of Java 8. Compared with abstract classes, they can all include abstract methods and method implementations:
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">interface ProjectService { val name: String val owner: String fun save(project: Project) fun print() { println("I am project") }}</code>
There is no constructor for the interface. We use the colon :
syntax to implement an interface, if there are multiple uses ,
commas are separated:
<code class="language-javascript">class ProjectServiceImpl : ProjectService // 跟继承抽象类语法一样,使用冒号class ProjectMilestoneServiceImpl : ProjectService, MilestoneService // 实现多个接口使用逗号( ,) 隔开</code>
When rewriting print()
function, because the ProjectService and MilestoneService we implement have a print()
function, when we use super.print()
directly, the compiler cannot know that the print function we want to call. We call this: overwrite conflict, as shown in the figure below

Coverage conflicts
At this time, we can use the following syntax to call:
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">super<ProjectService> .print()super<MilestoneService> .print()</code>4.4 object object
Singleton mode is very commonly used. It is a commonly used software design pattern. For example, the default bean in Spring is a singleton. Through the singleton mode, you can ensure that there is only one instance of a class in the system. That is, a class has only one object instance.
There are no static properties and methods in Kotlin, but an object singleton object can be declared using the keyword object
:
<code class="language-javascript">package com.easy.kotlinobject User { val username: String = "admin" val password: String = "admin" fun hello() { println("Hello, object !") }}fun main(args: Array<String> ) { println(User.username) // 跟Java的静态类一样的调用形式println(User.password) User.hello()}</code>
Kotlin also provides companion objects, declared using the companion object
keyword:
<code class="language-javascript">class DataProcessor { companion object DataProcessor { fun process() { println("I am processing data ...") } }}fun main(args: Array<String> ) { DataProcessor.process() // I am processing data ...}</code>
A class can only have 1 companion object.
4.5 Data ClassAs the name suggests, a data class is a class that only stores data and does not contain operational behavior. Kotlin's data class can save us a lot of boilerplate code (Java forces us to write a bunch of getters and setters, but in fact these methods are "self-explanatory"), so that the final code is easier to understand and easy to maintain.
Use the keyword to create a class that contains only data:
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">data class LoginUser(val username: String, val password: String)</code>
A convenient Kotlin toolbox is provided in IDEA, and we can decompile the above code into equivalent Java code. The steps are as follows
1. Menu bar selection: Tools -> Kotlin -> Show Kotlin Bytecode

Menu bar selection: Tools -> Kotlin -> Show Kotlin Bytecode
Click Decompile
Click Decompile
Decompiled Java code
Decompiled Java code
The complete Java code after decompilation is
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">public final class LoginUser { @NotNull private final String username; @NotNull private final String password; @NotNull public final String getUsername() { return this.username; } @NotNull public final String getPassword() { return this.password; } public LoginUser(@NotNull String username, @NotNull String password) { Intrinsics.checkParameterIsNotNull(username, "username"); Intrinsics.checkParameterIsNotNull(password, "password"); super(); this.username = username; this.password = password; } @NotNull public final String component1() { return this.username; } @NotNull public final String component2() { return this.password; } @NotNull public final LoginUser copy(@NotNull String username, @NotNull String password) { Intrinsics.checkParameterIsNotNull(username, "username"); Intrinsics.checkParameterIsNotNull(password, "password"); return new LoginUser(username, password); } // $FF: synthetic method // $FF: bridge method @NotNull public static LoginUser copy$default(LoginUser var0, String var1, String var2, int var3, Object var4) { if ((var3 & 1) != 0) { var1 = var0.username; } if ((var3 & 2) != 0) { var2 = var0.password; } return var0.copy(var1, var2); } public String toString() { return "LoginUser(username=" this.username ", password=" this.password ")"; } public int hashCode() { return (this.username != null ? this.username.hashCode() : 0) * 31 (this.password != null ? this.password.hashCode() : 0); } public boolean equals(Object var1) { if (this != var1) { if (var1 instanceof LoginUser) { LoginUser var2 = (LoginUser)var1; if (Intrinsics.areEqual(this.username, var2.username) && Intrinsics.areEqual(this.password, var2.password)) { return true; } } return false; } else { return true; } }}</code>
The compiler will automatically create the following functions from the properties declared in the main constructor:
equals() / hashCode() function toString() format is "LoginUser(username=" this.username ", password=" this.password ")"component1(), component2() function returns the attribute value of the corresponding subscript, and arranges copy() in the order of declaration. Function: Renew the old object attributes LoginUser(username, password) An object is outIf these functions are already explicitly defined in the class, or inherited from the superclass, the compiler will no longer be generated.
Data classes have the following restrictions:
The main constructor contains at least one parameter parameter must be identified as val or var cannot be abstract, open, sealed or inner cannot inherit other classes (but can implement interfaces)Additionally, data classes can be used in deconstruction declarations:
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">package com.easy.kotlindata class LoginUser(val username: String, val password: String)fun main(args: Array<String> ) { val loginUser = LoginUser("admin", "admin") val (username, password) = loginUser println("username = ${username}, password = ${password}") // username = admin, password = admin}</code>
The Kotlin standard library provides Pair and Triple data classes.
4.6 NotesAnnotation is to append metadata to the code. Metadata information is defined by the annotation kotlin.Metadata.
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">@Retention(AnnotationRetention.RUNTIME)@Target(AnnotationTarget.CLASS)internal annotation class Metadata</code>
This @Metadata information exists in all class files generated by the Kotlin compiler and is read by the compiler and reflection. For example, we declare an annotation using Kotlin
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">annotation class Suspendable // Java中使用的是@interface Suspendable</code>
Then, the compiler will generate the corresponding metadata information
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">@Retention(RetentionPolicy.RUNTIME)@Metadata( mv = {1, 1, 7}, bv = {1, 0, 2}, k = 1, d1 = {"\u0000\n\n\u0002\u0018\u0002\n\u0002\u0010\u001b\n\u0000\b\u0086\u0002\u0018\u00002\u00020\u0001B\u0000¨\u0006\u0002"}, d2 = {"Lcom/easy/kotlin/Suspendable;", "", "production sources for module kotlin_tutorials_main"})public @interface Suspendable {}</code>
Kotlin's annotations are fully compatible with Java's annotations. For example, we use Spring Data Jpa in Kotlin
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">interface ImageRepository : PagingAndSortingRepository<Image, Long> { @Query("SELECT a from #{#entityName} a where a.isDeleted=0 and a.isFavorite=1 and a.category like %:searchText% order by a.gmtModified desc") fun searchFavorite(@Param("searchText") searchText: String, pageable: Pageable): Page<Image> @Throws(Exception::class) @Modifying @Transactional @Query("update #{#entityName} a set a.isFavorite=1,a.gmtModified=now() where a.id=?1") fun addFavorite(id: Long)}</code>
It's basically the same as Java's annotations. Another example of code that Kotlin uses Spring MVC annotations
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">@Controllerclass MeituController { @Autowired lateinit var imageRepository: ImageRepository @RequestMapping(value = *arrayOf("/", "meituView"), method = arrayOf(RequestMethod.GET)) fun meituView(model: Model, request: HttpServletRequest): ModelAndView { model.addAttribute("requestURI", request.requestURI) return ModelAndView("meituView") }}</code>
From the above example, we can see that Kotlin uses Java frameworks very simple and convenient.
4.7 EnumerationIn Kotlin, the enum class keyword is used to declare an enum class. For example
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">enum class Direction { NORTH, SOUTH, WEST, EAST // 每个枚举常量都是一个对象, 用逗号分隔}</code>
Compared with string constants, type safety can be achieved using enumerations. The enumeration class has two built-in properties:
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript"> public final val name: String public final val ordinal: Int</code>
They represent the value and subscript positions of the enumeration object respectively. For example, the information of its enumeration object is as follows
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">>>> val north = Direction.NORTH>>> north.nameNORTH>>> north.ordinal0>>> north is Directiontrue</code>
Each enum is an instance of the enum class, and they can be initialized:
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">enum class Color(val rgb: Int) { RED(0xFF0000), GREEN(0x00FF00), BLUE(0x0000FF)}</code>
The information about the enumeration object of the enumeration color is as follows
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">>>> val c = Color.GREEN>>> cGREEN>>> c.rgb65280>>> c.ordinal1>>> c.nameGREEN</code>4.8 Internal Class 4.8.1 Normal nested Class
In Kotlin, classes can be nested. One class can be nested in other classes and can be nested with multiple layers.
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">class NestedClassesDemo { class Outer { private val zero: Int = 0 val one: Int = 1 class Nested { fun getTwo() = 2 class Nested1 { val three = 3 fun getFour() = 4 } } }}</code>
Test code:
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript"> val one = NestedClassesDemo.Outer().one val two = NestedClassesDemo.Outer.Nested().getTwo() val three = NestedClassesDemo.Outer.Nested.Nested1().three val four = NestedClassesDemo.Outer.Nested.Nested1().getFour()</code>
We can see that the way NestedClassesDemo.Outer.Nested().getTwo() in the code accesses nested classes is to directly use类名.
The number of layers of nested are used to access them.
Ordinary nested classes do not hold references to external classes, so they cannot access variables of external classes:
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">class NestedClassesDemo {class Outer { private val zero: Int = 0 val one: Int = 1 class Nested { fun getTwo() = 2 fun accessOuter() = { println(zero) // error, cannot access outer class println(one) // error, cannot access outer class } }}}</code>4.8.2 Nested inner classes
If a class Inner wants to access members of the external class Outer, you can add a modifier inner before this class. The inner class will have a reference to the object of the outer class:
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">package com.easy.kotlinclass NestedClassesDemo { class Outer { private val zero: Int = 0 val one: Int = 1 inner class Inner { fun accessOuter() = { println(zero) // works println(one) // works } } }}fun main(args: Array<String> ) { val innerClass = NestedClassesDemo.Outer().Inner().accessOuter()}</code>
We can see that when accessing inner class Inner
, we use Outer().Inner()
, which is an object reference that holds Outer. It is distinguished from the method of using class names to access it directly.
Anonymous inner class is an inner class without a name. Since it is an inner class, it can naturally access variables of the outer class.
We use object expressions to create an anonymous internal class instance:
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">class NestedClassesDemo { class AnonymousInnerClassDemo { var isRunning = false fun doRun() { Thread(object : Runnable { // 匿名内部类override fun run() { isRunning = true println("doRun : i am running, isRunning = $isRunning") } }).start() } }}</code>
If the object is a functional Java interface, that is, an instance of a Java interface with a single abstract method, such as the Runnable interface in the example above:
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript">@FunctionalInterfacepublic interface Runnable { public abstract void run();}</code>
We can create it using lambda expressions, and the following writing methods are all possible:
Code language: javascript Number of code runs: 0 run copy<code class="language-javascript"> fun doStop() { var isRunning = true Thread({ isRunning = false println("doStop: i am not running, isRunning = $isRunning") }).start() } fun doWait() { var isRunning = true val wait = Runnable { isRunning = false println("doWait: i am waiting, isRunning = $isRunning") } Thread(wait).start() } fun doNotify() { var isRunning = true val wait = { isRunning = false println("doNotify: i notify, isRunning = $isRunning") } Thread(wait).start() }</code>
We will introduce more about Lambda expressions and functional programming in the next chapter.
Summary of this chapterIn this chapter, we introduce the characteristics of Kotlin object-oriented programming: classes and constructors, abstract classes and interfaces, inheritance and combination, and also introduce the characteristics of Kotlin, such as annotation classes, enumeration classes, data classes, nested classes, internal classes, anonymous internal classes, singleton object objects, etc.
In general, in terms of the support of the object-oriented programming paradigm, Kotlin has added a lot of interesting functions and features to Java, which makes our code more convenient and quick.
We know that in Java 8, support for functional programming was introduced: Lambda expressions, Function interfaces, stream APIs, etc., while in Kotlin, support for functional programming is more comprehensive and rich, and the code is more concise and elegant. In the next chapter, let’s learn Kotlin’s functional programming together.
The above is the detailed content of Chapter 4 Class and Object-Oriented Programming Chapter 4 Class and Object-Oriented Programming. For more information, please follow other related articles on the PHP Chinese website!

The new Surface Pro: A step back? Microsoft's latest Surface Pro offers connectivity via two USB-C ports, supporting charging, USB 3.2 data transfer, and DisplayPort 1.4a (up to two 4K monitors at 60Hz). However, the device ships without a power ad

Microsoft's latest Surface Laptop aims to rival the MacBook Air, but with some notable compromises. The absence of a Surface Connect port marks a significant departure from previous models, reflecting the growing prevalence of Thunderbolt and USB do

1. Background Recently, when using the svn plug-in to manage remote warehouse code in eclipse, prompts to enter passwords are always prompted to enter passwords, which is particularly annoying. After hard work, I finally solved the problem and shared it with you~ 2. Analysis of the password mechanism of the svn plug-in and the cause of the problem. When we use the svn plug-in for the first time and enter the password, a file that saves the password will be generated, and then the svn plug-in will read the username and password information by default every time. When eclipse is started, the configuration information will be automatically read into the program cache. After the password of svn is modified, it is impossible to log in again, and there is no prompt to re-enter the password. At this time, we can delete the relevant configuration files and let the svn plugin prompt us to re-enter the password. However, ec

The steps to start system restore in Windows 8 are: 1. Press the Windows key X to open the shortcut menu; 2. Select "Control Panel", enter "System and Security", and click "System"; 3. Select "System Protection", and click "System Restore"; 4. Enter the administrator password and select the restore point. When selecting the appropriate restore point, it is recommended to select the restore point before the problem occurs, or remember a specific date when the system is running well. During the system restore process, if you encounter "The system restore cannot be completed", you can try another restore point or use the "sfc/scannow" command to repair the system files. After restoring, you need to check the system operation status, reinstall or configure the software, and re-back up the data, and create new restore points regularly.

"Modern Operating Systems (English Edition 3rd Edition)" is a classic work written by Professor Tanenbaum. With his profound experience in the design of three operating systems, the book perfectly integrates theory and practice. The third edition of the book explores a number of topics in depth, such as process, threading, storage management, file systems, I/O deadlock, interface design, multimedia, performance trade-offs, and introduces the latest trends in operating system design. The book not only explains the principles and practices of modern operating systems in detail, but also pays special attention to Linux operating systems, Windows Vista operating systems, embedded operating systems, real-time operating systems and multimedia operating systems. Covering Windows Vista and the latest Linux/Unix operations

1. The Origin of .NETCore When talking about .NETCore, we must not mention its predecessor .NET. Java was in the limelight at that time, and Microsoft also favored Java. The Java virtual machine on the Windows platform was developed by Microsoft based on JVM standards. It is said to be the best performance Java virtual machine at that time. However, Microsoft has its own little abacus, trying to bundle Java with the Windows platform and add some Windows-specific features. Sun's dissatisfaction with this led to a breakdown of the relationship between the two parties, and Microsoft then launched .NET. .NET has borrowed many features of Java since its inception and gradually surpassed Java in language features and form development. Java in version 1.6

1. Background Recently, out of curiosity, I updated the Windows 10 system, which is very easy to operate and the experience is quite good. However, when developing in IDEA, when starting the project using port 80, it is found that the port has been occupied. After some attempts, I found a solution and I will share it with you. 2. Solution steps 1. Check the process number PID that occupies port 80 by executing the netstat-ano|findstr "80" command. 2. Since port 80 is occupied by system services, the process cannot be terminated directly. Therefore, use the netshhttpshowservicestate command to view the current HTTP service status. The result is as shown in the figure: from the figure

Web development design is a promising career field. However, this industry also faces many challenges. As more businesses and brands turn to the online marketplace, web developers have the opportunity to demonstrate their skills and succeed in their careers. However, as demand for web development continues to grow, the number of developers is also increasing, resulting in increasingly fierce competition. But it’s exciting that if you have the talent and will, you can always find new ways to create unique designs and ideas. As a web developer, you may need to keep looking for new tools and resources. These new tools and resources not only make your job more convenient, but also improve the quality of your work, thus helping you win more business and customers. The trends of web development are constantly changing.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

ZendStudio 13.5.1 Mac
Powerful PHP integrated development environment

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Dreamweaver Mac version
Visual web development tools

Dreamweaver CS6
Visual web development tools

Safe Exam Browser
Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.
