Kotlin using (ii) Classes and objects

Source: Internet
Author: User
Tags abstract anonymous constant constructor inheritance modifiers visibility
Classes and Inheritance

class

Declaring a class using the keyword class in Kotlin

Class Invoice {
}

A class declaration consists of a class name, a class header (specifying its type parameter, a main constructor, and so on) and a class body surrounded by curly braces. Both the class head and the class body are optional, and if a class does not have a class body, the curly braces can be omitted.

Class Empty

constructor Function

A class in Kotlin can have one primary constructor and one or more secondary constructors. The main constructor is part of the class header: It follows the class name (and optionally the type parameter).

Class person Constructor (firstname:string) {
}

If the primary constructor does not have any annotations or visibility modifiers, you can omit the constructor keyword.

Class Person (firstname:string) {
}

The main constructor cannot contain any code. The initialized code can be placed in an initialization block (initializer blocks) prefixed with the INIT keyword:

Class Customer (name:string) {
    init {
        logger.info ("Customer initialized with value ${name}")
    }
}

Note that the parameters of the main construct can be used in the initialization block. They can also be used in a property initializer declared within a class:

Class Customer (name:string) {
    val customerkey = Name.touppercase ()
}

In fact, Kotlin has a concise syntax for declaring properties and initializing properties from the main constructor:

Class Person (Val firstname:string, Val lastname:string, var age:int) {
    //...
}

As with normal properties, the attributes declared in the main constructor can be variable (VAR) or read-only (Val).

If the constructor has annotations or visibility modifiers, this constructor keyword is required, and these modifiers precede it:

Class Customer public @Inject constructor (name:string) {...}

Secondary constructor

The constructor class can also declare a secondary constructor with a prefix:

Class Person {
    Constructor (Parent:person) {
        Parent.children.add (this)
    }
}

If a class has a primary constructor, each secondary constructor needs to be delegated to the main constructor, either directly or indirectly through another secondary constructor. Another constructor that delegates to the same class is used with the This keyword:

Class Person (Val name:string) {
    constructor (name:string, Parent:person): This (name) {
        Parent.children.add ( This)
    }
}

If a non-abstract class does not declare any (primary or secondary) constructors, it will have a generated primary constructor without parameters. The visibility of the constructor is public. If you do not want your class to have a public constructor, you need to declare an empty primary constructor with non-default visibility:

Class Dontcreateme Private Constructor () {
}

Note: On the JVM, if all parameters of the primary constructor have default values, the compiler generates an additional parameterless constructor that will use the default values. This makes it easier for Kotlin to use libraries such as Jackson or JPA to create instances of classes through the parameterless constructor.

Class Customer (val customername:string = "")

to create an instance of a class

To create an instance of a class, we call the constructor like a normal function:

Val invoice = Invoice ()

val customer = Customer ("Joe Smith")

Note that Kotlin does not have the new keyword.

Nested classes

Classes can be nested within other classes

Class Outer {
    private val bar:int = 1
    class Nested {fun
        foo () = 2
    }
}

val demo = outer.nested (). Foo ()//= = 2

Inner class

A class can be marked as inner to be able to access members of an external class. The inner class will have a reference to an object of the external category:

Class Outer {
    private val bar:int = 1
    inner class Inner {fun
        foo () = Bar
    }
}

val demo = Outer ( ). Inner (). Foo ()//= = 1

See the qualified this expression for the disambiguation usage of this in the inner class.

Anonymous inner class

To create an anonymous inner class instance using an object expression:

Window.addmouselistener (Object:mouseadapter () {
    override fun mouseclicked (e:mouseevent) {
        //...
    }

    Override Fun Mouseentered (e:mouseevent) {
        //...
    }
})

If the object is an instance of a functional Java interface (that is, a Java interface with a single abstract method), you can create it using a lambda expression with an interface-type prefix:

Val Listener = actionlistener {println ("clicked")}

Class Member

Classes can contain constructors and initialization block function properties nested classes and Inner class object declaration inheritance

In Kotlin, all classes have a common superclass of any, which is the default superclass for classes that do not have a super-type declaration:

Class Example//implicitly inherit from any

Any is not a java.lang.Object; In particular, it has no members except Equals (), Hashcode (), and ToString (). Refer to the Java Interoperability section for more details.

To declare an explicit super-type, we put the type after the colon of the class header:

Open Class Base (P:int)

class Derived (p:int): Base (P)

If the class has a primary constructor, its base type can (and must) be initialized in-place with the main constructor parameter (the base type).

If the class does not have a primary constructor, each secondary constructor must initialize its base type with the Super keyword, or delegate to another constructor to do so. Note that in this case, different secondary constructors can call different constructors of the base type:

Class Myview:view {
    constructor (Ctx:context): Super (CTX)

    Constructor (Ctx:context, Attrs:attributeset): Supe R (CTX, Attrs)
}

The open callout on the class is opposite to final in Java, which allows other classes to inherit from this class. By default, all of the classes in Kotlin are final.

Override method

As we have mentioned before, Kotlin strives for clarity and explicit expression. Unlike Java, Kotlin needs to explicitly label the members that can be overwritten (which we call Open) and the members after they are overwritten:

Open Class Base {
    Open Fun V () {} ' Fun
    NV () {}
} '
class Derived (): Base () {
    override Fun V () {}
}}

The override callout must be added to the DERIVED.V () function. If not written, the compiler will error. If the function does not label open such as BASE.NV (), a function that defines the same signature is not allowed in the subclass, regardless of the addition of override. Open members are forbidden in a final class (classes that are not labeled with open).

The member marked as override is itself open, that is, it can be overridden in a subclass. If you want to prohibit overwriting again, use the final keyword:

Open Class anotherderived (): Base () {
    final override fun V () {}
}

overriding properties

Property overrides are similar to method overrides, and properties that are declared in a superclass and then re-declared in a derived class must start with override, and they must have compatible types. The properties of each claim can be overridden by properties that have initializers or properties that have getter methods.

Open Class Foo {
    open val x:int get {...}
}

Class Bar1:foo () {
    override Val X:int = ...
}

You can also overwrite a Val attribute with a var attribute, but not vice versa. This is allowed because a Val attribute essentially declares a getter method, and overwriting it as Var simply declares an additional setter method in the subclass.

Note that you can use the Override keyword in the main constructor as part of the property declaration.

interface Foo {
    val count:int
}

class Bar1 (override Val count:int): Foo

class Bar2:foo {
    override var count:int = 0
}

Override Rule

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 this member and provide its own implementation (perhaps one of them with inheritance). In order to represent the implementation from which the superclass inherits, we use the super, which is qualified by the superclass name in angle brackets, such as super:

Open Class A {
    open fun f () {print ("a")} Fun
    A () {print ("a")}
}

interface B {fun
    f () {print ("B"  }///interface member default is "open" fun
    B () {print ("B")}
}

class C (): A (), B {
    //compiler requires override F ():
    override Fun F () {
        super<a>.f ()//Call A.F ()
        super<b>.f ()//Call B.F ()
  }
}

Inheriting A and b at the same time is not a problem, and a () and B () are also not problematic because C inherits only one implementation of each function. But F () inherits two implementations from C, so we have to cover F () in C and provide our own implementations to disambiguate.

Abstract class

A class and some of its members can be declared abstract. Abstract members may not be implemented in this class. It is important to note that we do not need to annotate an abstract class or function with open.

We can overwrite a non-abstract open member with an abstract member.

Open Class Base {
    open fun F () {}
}

abstract class Derived:base () {
    override abstract fun F ()
}

Interface

The Kotlin interface is similar to Java 8, containing both the declaration of the abstract method and the implementation. Unlike an abstract class, an interface cannot hold a state. It can have properties but must be declared as abstract or provide an accessor implementation.

Use keyword interface to define interfaces

Interface MyInterface {fun
    bar () Fun
    foo () {
      //optional method Body
    }
}

Implementing interfaces

A class or object can implement one or more interfaces.

Class Child:myinterface {
    override Fun bar () {
        //method body
    }
}

Properties in the interface

You can define properties in the interface. Properties declared in an interface are either abstract or provide an implementation of accessors. Properties declared in an interface cannot have behind-the-scenes fields (backing field), so accessors declared in an interface cannot reference them.

Interface MyInterface {
    val prop:int//abstract

    val propertywithimplementation:string
        get () = "foo" Fun

    foo () {
        print (prop)
    }
}

class Child:myinterface {
    override val Prop:int = $
}

Resolve Overwrite Conflicts

When you implement multiple interfaces, you may encounter an issue in which the same method inherits multiple implementations. For example

Interface A {fun
    foo () {print ("A")} Fun
    bar ()
}

interface B {fun
    foo () {print ("B")}
    Fu N Bar () {print ("Bar")}
}

class C:a {
    override Fun bar () {print ("Bar")}
}

class D:a, B {
  override Fun foo () {
        super<a>.foo ()
        Super<b>.foo ()
    }

    override Fun Bar () {
        Super<b>.bar ()
    }
}

In the example above, interfaces A and B both define the method foo () and bar (). Both implement Foo (), but only B implements Bar () (bar () is not marked abstract in A, because the default is abstract when there is no method body. Because C is a concrete class that implements a, you must rewrite bar () and implement this abstract method.

However, if we derive d from A and B, we need to implement all of the methods we inherit from multiple interfaces and indicate how D should implement them. This rule applies both to methods that inherit a single implementation (bar ()) and to methods that inherit multiple implementations (foo ()).

generic type

Similar to Java, classes in Kotlin can have type parameters:

Class Box<t> (t:t) {
    var value = T
}

In general, to create an instance of such a class, we need to provide the type parameter:

Val box:box<int> = box<int> (1)

However, if the type parameter can be inferred, such as from the arguments of the constructor or from other means, the omitted type parameter is allowed:

Val box = box (1)//1 has type Int, so the compiler knows we're talking about box<int>.

More Introduction to Generics

Enum class

The most basic use of enum classes is to implement type-safe enumeration

Enum class Direction {North
    , South, WEST, EAST
}

Each enumeration constant is an object. Enumeration constants are separated by commas.

Initialization

Because each enumeration is an instance of an enumeration class, they can be initialized.

Enum Class Color (Val rgb:int) {
        RED (0xFF0000),
        GREEN (0x00FF00),
        BLUE (0x0000FF)
}

Anonymous class

Enumeration constants can also declare their own anonymous classes

Enum class Protocolstate {
    waiting {
        override fun signal () = Talking
    },

    talking {
        override fun signal () = Waiting
    };

    Abstract Fun Signal (): Protocolstate
}

and corresponding methods, as well as methods to cover the base class. Note that if the enumeration class defines any members, use semicolons to separate the enumeration constant definitions in the member definition, as in Java.

Using enumeration constants

As in Java, the enumeration classes in Kotlin also have synthetic methods that allow you to list the enumerated constants you define and get enumerated constants by name. The signatures of these methods are as follows (assuming the name of the enumeration class is Enumclass):

Enumclass.valueof (value:string): Enumclass
enumclass.values (): array<enumclass>

If the specified name does not match any of the enumeration constants defined in the class, The ValueOf () method throws a IllegalArgumentException exception.

From Kotlin 1.1, you can use the EnumValues () and enumvalueof () functions to access constants in the enumeration class in a generic manner:

Enum class RGB {RED, GREEN, BLUE}

inline Fun <reified t:enum<t>> printallvalues () {
    print (Enumvalu Es<t> (). jointostring {it.name})
}

printallvalues<rgb> ()//Output RED, GREEN, BLUE

Each enumeration constant has a property that gets its name and location in the enumeration class declaration:

Val name:string
Val ordinal:int

Enumeration constants also implement the comparable interface, in which the natural order is the order in which they are defined in the enumeration class.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.