카톡
◎위챗 : speedseoul
In Part 3, I introduced some aspects of object-oriented programming (OOP) for Kotlin. In this article, I will continue to introduce other aspects of OOP.
We can use interfaces the way we are used in Java. A Kotlin interface method can have a default implementation. Unlike Java 8, which requires the default keyword, Kotlin has no special annotation for such methods: you just provide a method body. Example:
Kotlin interfaces can have properties but these need to be abstract or to provide accessor implementations. Example:
We can implement interfaces in a class look like this:
Kotlin doesn’t support multiple inheritances, however, the same thing can be achieved by implementing more than two interfaces at a time.
Like most other aspects of Kotlin, data classes aim to reduce the amount of boilerplate code you write in your project. Data classes provide compiler-generated equals() , hashCode() , toString() , copy() , and other methods. An example of a normal class:
We create an object from the Person class:
The result can look like this:
Now, we change the Person class to become a data class by using data keyword as follows:
We create an object from the Person class again:
The result can look like this:
If we declare some properties inside Person class body as follows:
Creating an object
The result also looks like this:
This is because the compiler only uses the properties defined inside the primary constructor for toString() , equals() , hashCode() , and copy() implementations.
We also can use the copy() method copy an object altering some of its properties. An example:
In Kotlin, classes can be nested in other classes:
A class may be marked as inner to be able to access members of outer class. Inner classes carry a reference to an object of an outer class:
When you evaluate an expression using the when construct, the Kotlin compiler forces you to check for the default option. Example:
If you add a new subclass, the compiler won’t detect that something has changed. If you forget to add a new branch, the default one will be chosen, which can lead to subtle bugs. Kotlin provides a solution to this problem: : sealed classes. Let’s look at the following example:
If you handle all subclasses of a sealed class in a when statement, you don’t need to provide the default branch.
In this application, I created an UI as follows:

We can input the first value, the second value, and choose an operator as follows:

Click the CALCULATE button, the result can look like this:

Some controls are used in this application:
Control | ID attribute | Text attribute |
EditText | value1 | @string/value1 |
EditText | value2 | @string/value2 |
EditText | result | @string/result |
RadioButton | add | @string/add |
RadioButton | sub | @string/sub |
RadioButton | mul | @string/mul |
RadioButton | div | @string/div |
RadioGroup | operators | |
Button | calculate | @string/calculate |
(You can see source code of activity_main.xml and strings.xml files here)
In the MainActivity.kt, the first, I created the sealed class named Expr and its subclasses:
In MainActivity class, I created the eval function:
In OnClickListener, I got some inputs, assigned them to variables, and checked if a string is numeric or not using regular expressions (regex):
The finally, I wrote some code:
I also didn’t forget to set Click event for the CALCULATE button:
Run application again:

You input texts for the first value and second value as follows:

Choose an operator and click the CALCULATE button, the result looks like this:

You can download my source here and I hope you have a great experience.