1. Classes and Objects
1. Class
The declarations of Kotlin and Java classes are the same, which are represented by class, such as
class TestClass {
}
If it is an empty class, the curly brackets can be omitted
2. Constructor
A primary constructor and multiple secondary functions, the primary function is after the class name, such as
class TestClass {
//主函数
class TestClass constructor(firstName: String) {
init {
print("这里初始化")
}
}
}
The constructor keyword can be omitted if the primary constructor does not have any annotations or visibility modifiers.
and the primary constructor does not allow any code, the initialization code can be placed in the init block
Let's look at the next constructor
Classes can also declare secondary constructors prefixed with constructor:
class Person {
constructor(parent: Person) {
parent.children.add(this)
}
}
3. Instantiate the class object
There is no new in Kotlin, so call it directly
class TestClass {
//主函数
class TestClass constructor(firstName: String) {
init {
print("这里初始化")
}
}
constructor(firstName: String) {
print("次构造函数")
}
}
class Test{
//实例化类对象
val test = TestClass("lgl");
}
2. Inheritance
All classes have a superclass Any, which is somewhat similar to Object in JAVA, but they are indeed different, but the concept is similar, because Any has only a few methods
Here we define a base class BaseClass
open class BaseClass {
class BaseClass constructor(str:String){
}
}
The open here means public, which is the exact opposite of final in JAVA
Then we define another class to inherit the base class
class SonClass : BaseClass(){
}
Of course, the parentheses can be canceled
If the class does not have a primary constructor, then each secondary constructor must use the super keyword to initialize its base type, as we use in Android
class MyView : View {
constructor(ctx: Context) : super(ctx)
constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs)
}
3. Coverage
This is easy to understand, it can be overridden with inheritance, let's look at a piece of code
open class Base {
open fun v() {
print("Base...")
}
fun nv() {}
}
class Son() : Base() {
override fun v() {
print("Son...")
}
}
fun main(args: Array<String>) {
val son = Son();
son.v()
}
There is a Base modified by open, there is a Base method in it, and there is printing in it. I now have a Son class, which inherits Base, and overrides the v method with override modification, and then prints it. Then my main method instantiates this object. After the call, the print is Son...
A member marked as override is itself open, that is, it can be overridden in subclasses, and if you don't want to be overridden again, you can modify a final
The above mentioned is the overriding of the method, we can also override the property, but it is the same, need to override the modification, such as
open class Base {
open var a = 9;
open fun v() {
print("Base...")
}
fun nv() {}
}
class Son() : Base() {
override var a = 8;
override fun v() {
print("Son...")
}
}
fun main(args: Array<String>) {
val son = Son();
son.v()
print(son.a)
}
In this code, we can see that an attribute a is defined in the base class, and then an a is overwritten in the subclass, and the output is the a value of the subclass
If we want to use the method of the parent class, we can use super
class Son() : Base() {
override var a = 8;
override fun v() {
super.v()
print("Son...")
}
}
If you want to use it in an inner class, you need [email protected]()
In Kotlin, implementation inheritance is governed by the following rules: if a class inherits multiple implementations of the same member from its immediate superclass, it must override the member and provide its own implementation (perhaps with one of the inherited
ones ) a). To indicate which supertype to inherit from, we use super qualified by the supertype name in angle brackets, as in super:
open class A {
open fun f() { print("A") }
fun a() { print("a") }
}
interface B {
fun f() { print("B") } // 接⼝成员默认就是“open”的
fun b() { print("b") }
}
class C() : A(), B {
// 编译器要求覆盖 f():
override fun f() {
super<A>.f() // 调⽤ A.f()
super<B>.f() // 调⽤ B.f()
}
}
4. Abstract class
abstract class Impl{
abstract open fun f()
}
class Impl1():Impl(){
override fun f() {
}
}
The open here can not be declared, and we can cover a non-abstract open member with an abstract member, as in the example
open class Base {
open fun f() {}
}
abstract class Derived : Base() {
override abstract fun f()
}
5. Attributes and Fields
I believe that everyone should have a better understanding of attributes, as we have already said in the second article
class H {
var a: String = "Hello"
var b: Int = 0
var c: Boolean = true;
}
if you want to call
fun main(args: Array<String>) {
val h = H();
print("a:${h.a}b:${h.b}c:${h.c}")
}
In kt, get and set are more interesting. The correct syntax is:
var <propertyName>[: <PropertyType>] [= <property_initializer>]
[<getter>]
[<setter>]
The following code
class H {
var a: String
get() = this.toString()
set(value) {
a == value
}
var b: Int = 0
val c: Boolean = true
}
I defined the get and set of a
6. Interface
The keyword interface of kt's interface, such as
interface Impl {
fun A()
fun B() {
//可选方法体
}
}
If you want to implement an interface, you can
class Tests : Impl {
override fun A() {
}
//B方法可以不需要实现
}
You can also define some properties in the interface, but they must be abstract or provide access to the outside world
interface Impl {
//抽象
val a: String
val b: String
get() = "Hello"
fun A()
fun B() {
//可选方法体
}
}
class Tests() : Impl {
override val a: String = "Hello"
override fun A() {
}
//B方法可以不需要实现
}
7. Visibility modifiers
There are four visibility modifiers in kt, private, protected, internal and public, the default is public
public everywhere
private declaration is visible in his file
internal same module is visible
protected does not apply to top-level declarations
Another point to note here is that in JAVA, the variables modified in our private can finally be accessed through set/get, but in kt, the outer class cannot access the private members modified by the inner class
8. Expansion
Extensions, extending new functionality of a class or object without subclassing the class or using any kind of design pattern like decorators
To declare an extension function, we need a receiver type, which is the type to be extended, as its prefix. Let's see the code:
fun main(args: Array<String>) {
val a = listOf<Int>()
a.open(1, 2)
}
//扩展List一个open方法
fun List<Int>.open(a: Int, b: Int) {
print(a + b)
}
It is very clear here. A List does not have an open method. I added it by extension, and internally realized the result of the output that I want to add.
Of course , we are not limited to which types, so through generics to decorate
//扩展List一个open方法
fun <T> List<T>.open(a: Int, b: Int) {
print(a + b)
}