国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Home System Tutorial Windows Series Chapter 4 Class and Object-Oriented Programming Chapter 4 Class and Object-Oriented Programming

Chapter 4 Class and Object-Oriented Programming Chapter 4 Class and Object-Oriented Programming

May 07, 2025 pm 04:42 PM
windows computer access tool ai Object-Oriented Programming the difference spring mvc java framework arrangement standard library Character

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 programming

In 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:

Chapter 4 Class and Object-Oriented Programming Chapter 4 Class and Object-Oriented Programming

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:

Chapter 4 Class and Object-Oriented Programming Chapter 4 Class and Object-Oriented Programming

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

Chapter 4 Class and Object-Oriented Programming Chapter 4 Class and Object-Oriented Programming

The core concept of object-oriented programming

4.2 Declaration Class

This section introduces the declarations of classes and constructors in Kotlin.

4.2.1 Empty Class

Use 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="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="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="javascript">class Person(var name: String, var age: Int, var sex: String) { // 聲明類和構(gòu)造函數(shù)override fun toString(): String { // override關(guān)鍵字,重寫toString() return "Person(name=&#39;$name&#39;, age=$age, sex=&#39;$sex&#39;)" }}</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="javascript">val person = Person("Jack", 29, "M")println("person = ${person}")</code>

Output

Code language: javascript Number of code runs: 0 run copy
 <code class="javascript">person = Person(name=&#39;Jack&#39;, age=29, sex=&#39;M&#39;)</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="javascript">class Person1 { lateinit var name: String // lateinit 關(guān)鍵字表示該屬性延遲初始化var age: Int = 0 // lateinit 關(guān)鍵字不能修飾primitive 類型lateinit var sex: String override fun toString(): String { return "Person1(name=&#39;$name&#39;, age=$age, sex=&#39;$sex&#39;)" }}</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="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="javascript">person1 = Person1(name=&#39;Jack&#39;, age=29, sex=&#39;M&#39;)</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="javascript">class Person2() { // 無參的主構(gòu)造函數(shù)lateinit var name: String var age: Int = 0 lateinit var sex: String constructor(name: String) : this() { // this 關(guān)鍵字指向當(dāng)前類對象實例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=&#39;$name&#39;, age=$age, sex=&#39;$sex&#39;)" }}</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="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)

Chapter 4 Class and Object-Oriented Programming Chapter 4 Class and Object-Oriented Programming

Right-click the mouse operation

After clicking, the dialog box pops up: Generate secondary constructor
Chapter 4 Class and Object-Oriented Programming Chapter 4 Class and Object-Oriented Programming

Select Generate

Select the constructor parameters
Chapter 4 Class and Object-Oriented Programming Chapter 4 Class and Object-Oriented Programming

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="javascript">constructor()</code>

Select a name attribute to generate

Code language: javascript Number of code runs: 0 run copy
<code class="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="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="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="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="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 interfaces

Abstract 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

Chapter 4 Class and Object-Oriented Programming Chapter 4 Class and Object-Oriented Programming

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 members

Abstraction 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

Chapter 4 Class and Object-Oriented Programming Chapter 4 Class and Object-Oriented Programming

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="javascript">package com.easy.kotlinabstract class Shapeclass Rectangle : Shape() // 繼承類的語法是使用冒號: , 父類需要在這里使用構(gòu)造函數(shù)初始化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="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="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="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="javascript">class Rectangle(override var width: Double, override var heigth: Double, override var radius: Double) : Shape() { // 聲明類的同時也聲明了構(gòu)造函數(shù)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="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="javascript">abstract class Shape { ... fun onClick() { // 默認(rèn)是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="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="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="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="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 Interface

An 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="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="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 language: javascript Number of code runs: 0 run copy
 <code class="javascript">class ProjectServiceImpl : ProjectService // 跟繼承抽象類語法一樣,使用冒號class ProjectMilestoneServiceImpl : ProjectService, MilestoneService // 實現(xiàn)多個接口使用逗號( ,) 隔開</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

Chapter 4 Class and Object-Oriented Programming Chapter 4 Class and Object-Oriented Programming

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="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 language: javascript Number of code runs: 0 run copy
 <code class="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的靜態(tài)類一樣的調(diào)用形式println(User.password) User.hello()}</code>

Kotlin also provides companion objects, declared using the companion object keyword:

Code language: javascript Number of code runs: 0 run copy
 <code class="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 Class

As 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="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

Chapter 4 Class and Object-Oriented Programming Chapter 4 Class and Object-Oriented Programming

Menu bar selection: Tools -> Kotlin -> Show Kotlin Bytecode

Click Decompile
Chapter 4 Class and Object-Oriented Programming Chapter 4 Class and Object-Oriented Programming

Click Decompile

Decompiled Java code
Chapter 4 Class and Object-Oriented Programming Chapter 4 Class and Object-Oriented Programming

Decompiled Java code

The complete Java code after decompilation is

Code language: javascript Number of code runs: 0 run copy
 <code class="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 out

If 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="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 Notes

Annotation 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="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="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="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="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="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 Enumeration

In 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="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="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="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="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="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="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="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="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="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.

4.8.3 Anonymous internal class

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="javascript">class NestedClassesDemo { class AnonymousInnerClassDemo { var isRunning = false fun doRun() { Thread(object : Runnable { // 匿名內(nèi)部類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="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="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 chapter

In 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!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

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

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

LayerZero, StarkNet, ZK Ecological Preheat: How long can the airdrop bonus last? LayerZero, StarkNet, ZK Ecological Preheat: How long can the airdrop bonus last? Jul 16, 2025 am 10:06 AM

The duration of the airdrop dividend is uncertain, but the LayerZero, StarkNet and ZK ecosystems still have long-term value. 1. LayerZero achieves cross-chain interoperability through lightweight protocols; 2. StarkNet provides efficient and low-cost Ethereum L2 expansion solutions based on ZK-STARKs technology; 3. ZK ecosystem (such as zkSync, Scroll, etc.) expands the application of zero-knowledge proof in scaling and privacy protection; 4. Participation methods include the use of bridging tools, interactive DApps, participating test networks, pledged assets, etc., aiming to experience the next generation of blockchain infrastructure in advance and strive for potential airdrop opportunities.

The role of Ethereum smart contracts The role of Ethereum smart contracts Jul 15, 2025 pm 09:18 PM

The role of Ethereum smart contract is to realize decentralized, automated and transparent protocol execution. Its core functions include: 1. As the core logic layer of DApp, it supports token issuance, DeFi, NFT and other functions; 2. Automatically execute contracts through code to reduce the risks of human intervention and fraud; 3. Build a DeFi ecosystem so that users can directly conduct financial operations such as lending and transactions; 4. Create and manage digital assets to ensure uniqueness and verifiability; 5. Improve the transparency and security of supply chain and identity verification; 6. Support DAO governance and realize decentralized decision-making.

Who is suitable for stablecoin DAI_ Analysis of decentralized stablecoin usage scenarios Who is suitable for stablecoin DAI_ Analysis of decentralized stablecoin usage scenarios Jul 15, 2025 pm 11:27 PM

DAI is suitable for users who attach importance to the concept of decentralization, actively participate in the DeFi ecosystem, need cross-chain asset liquidity, and pursue asset transparency and autonomy. 1. Supporters of the decentralization concept trust smart contracts and community governance; 2. DeFi users can be used for lending, pledge, and liquidity mining; 3. Cross-chain users can achieve flexible transfer of multi-chain assets; 4. Governance participants can influence system decisions through voting. Its main scenarios include decentralized lending, asset hedging, liquidity mining, cross-border payments and community governance. At the same time, it is necessary to pay attention to system risks, mortgage fluctuations risks and technical threshold issues.

The flow of funds on the chain is exposed: What new tokens are being bet on by Clever Money? The flow of funds on the chain is exposed: What new tokens are being bet on by Clever Money? Jul 16, 2025 am 10:15 AM

Ordinary investors can discover potential tokens by tracking "smart money", which are high-profit addresses, and paying attention to their trends can provide leading indicators. 1. Use tools such as Nansen and Arkham Intelligence to analyze the data on the chain to view the buying and holdings of smart money; 2. Use Dune Analytics to obtain community-created dashboards to monitor the flow of funds; 3. Follow platforms such as Lookonchain to obtain real-time intelligence. Recently, Cangming Money is planning to re-polize LRT track, DePIN project, modular ecosystem and RWA protocol. For example, a certain LRT protocol has obtained a large amount of early deposits, a certain DePIN project has been accumulated continuously, a certain game public chain has been supported by the industry treasury, and a certain RWA protocol has attracted institutions to enter.

Which is better, DAI or USDC?_Is DAI suitable for long-term holding? Which is better, DAI or USDC?_Is DAI suitable for long-term holding? Jul 15, 2025 pm 11:18 PM

Is DAI suitable for long-term holding? The answer depends on individual needs and risk preferences. 1. DAI is a decentralized stablecoin, generated by excessive collateral for crypto assets, suitable for users who pursue censorship resistance and transparency; 2. Its stability is slightly inferior to USDC, and may experience slight deansal due to collateral fluctuations; 3. Applicable to lending, pledge and governance scenarios in the DeFi ecosystem; 4. Pay attention to the upgrade and governance risks of MakerDAO system. If you pursue high stability and compliance guarantees, it is recommended to choose USDC; if you attach importance to the concept of decentralization and actively participate in DeFi applications, DAI has long-term value. The combination of the two can also improve the security and flexibility of asset allocation.

How much is a stablecoin USD How much is a stablecoin USD Jul 15, 2025 pm 09:57 PM

The value of stablecoins is usually pegged to the US dollar 1:1, but it will fluctuate slightly due to factors such as market supply and demand, investor confidence and reserve assets. For example, USDT fell to $0.87 in 2018, and USDC fell to around $0.87 in 2023 due to the Silicon Valley banking crisis. The anchoring mechanism of stablecoins mainly includes: 1. fiat currency reserve type (such as USDT, USDC), which relies on the issuer's reserves; 2. cryptocurrency mortgage type (such as DAI), which maintains stability by over-collateralizing other cryptocurrencies; 3. Algorithmic stablecoins (such as UST), which relies on algorithms to adjust supply, but have higher risks. Common trading platforms recommendations include: 1. Binance, providing rich trading products and strong liquidity; 2. OKX,

Is USDC safe? What is the difference between USDC and USDT Is USDC safe? What is the difference between USDC and USDT Jul 15, 2025 pm 11:48 PM

USDC is safe. It is jointly issued by Circle and Coinbase. It is regulated by the US FinCEN. Its reserve assets are US dollar cash and US bonds. It is regularly audited independently, with high transparency. 1. USDC has strong compliance and is strictly regulated by the United States; 2. The reserve asset structure is clear, supported by cash and Treasury bonds; 3. The audit frequency is high and transparent; 4. It is widely accepted by institutions in many countries and is suitable for scenarios such as DeFi and compliant payments. In comparison, USDT is issued by Tether, with an offshore registration location, insufficient early disclosure, and reserves with low liquidity assets such as commercial paper. Although the circulation volume is large, the regulatory recognition is slightly low, and it is suitable for users who pay attention to liquidity. Both have their own advantages, and the choice should be determined based on the purpose and preferences of use.

Virtual currency Bitcoin trading platform Virtual currency Bitcoin trading platform Jul 15, 2025 pm 10:15 PM

Security and personal needs should be given priority when choosing a Bitcoin trading platform. 1. Binance is a world-leading platform, providing rich trading pairs and low fees; 2. OKX has strong technical strength and supports multiple trading modes; 3. Gate.io currency selection is numerous and the community is active; 4. Huobi interface is simple and easy to use; 5. KuCoin focuses on user experience; 6. Kraken is highly compliant; 7. BITFINEX is suitable for professional traders; 8. Bitstamp is simple to operate. Each platform has its own advantages, and users need to choose according to their own situation.

See all articles