Define the class inheritance structure

Interfaces in Kotlin

The following figure declares an interface with a single abstract method named click, which all non-abstract classes that implement the interface must provide



Kotlin uses the colon instead of the extends and implements keywords. Like Java, a class can implement multiple interfaces but can only inherit from one class



The override modifier is mandatory in KotlinThis avoids accidental overrides caused by writing out the implementation method before adding the abstract method

Whereas an interface method can have a default implementation, and Java8 requires you to annotate such an implementation with the default keyword, kotlin has no special annotations and only needs to provide a method body



Now define a Focusable interface that also implements a showOff method

When your class implements these two interfaces, you don’t use either implementation,The compiler will ask you to provide your own implementation



Modify the MyButton class as follows



To invoke an inherited implementation, the super keyword can be used, but the syntax for selecting a particular implementation is different,In Java it is Clickable.super.showoff (), while in Kotlin it is super< Clickable>.showoff ()

Implement an interface containing a method body in Java

Kotlin1.0 was designed with Java 6 in mind and does not support default methods in interfaces, so it compiles each interface with a default method into a combination of a normal interface and a class that uses the method body as a static function.

Open, final, abstract modifiers: Final by default

In Java, you are allowed to subclass any class and override any method unless the final keyword is explicitly called. Making changes to a base class can lead to incorrect behavior by subclasses. This is known as a vulnerable base class problem, because the base class code changes no longer match the assumptions made in its subclasses. Any changes to the base class may result in behavior changes outside of the subclass.

In Java classes and methods are open by default, and in Kotlin classes and methods are final by default.

If you want to allow subclasses of a class, use the open modifier to identify the class and add the open modifier to every property and method that can be overridden



If you override a member of a base class or interface, the overridden member is also open by default,If you want to prevent a subclass of your class from overwriting your implementation, you can explicitly mark the overridden member as final

Open classes and smart transformations

The class default final makes smart conversions possible ina wide variety of scenarios. We mentioned earlier that smart conversions can only be used on variables that have not changed since type checking. For a class, this means that smart conversions can only be used on class attributes of type Val that have no custom accessors. This premise implies that the property must be final, otherwise a subclass that can override the property and define a custom accessor would break the key premise of intelligent transformation

In Kotlin, you can declare a class as abstruct, and that class cannot be instantiated. It usually contains some abstract members that are not implemented and must be overridden in subclasses. Abstract members are always open, so there is no need to use open explicitly

Class access modifier Members of the relevant commentary
final Can’t be rewritten Class members used by default
open Can be rewritten Need to make it clear
abstruct Must be rewritten Can only be used in abstract classes. Abstract members cannot have implementations
override Overrides a member of a parent class or interface If I don’t say final. Overridden members are left open by default

Visibility modifier: Defaults to public

Kotlin is almost identical to Java, but by default kotlin is public. A new modifier is also provided: internal (visible only inside a module), where a module is a set of Kotlin files compiled together, possibly an IDEA module, a set of files compiled using calls to Ant tasks, and so on. Kotlin also allows the use of private in top-level declarations, including classes, functions, and attributes, which are visible only in the file in which they are declared

Visibility modifier Members of the class The top statement
public Visible everywhere Visible everywhere
internal Visible in module Visible in module
protected Visible in subclasses There is no
private Seen in class Visible in the file

Kotlin disallowed referencing the low-visibility type TalkativeButton (internal) from the public function giveSpeech. General rule: The underlying type of a class and all classes used in the type argument list, or the signature of a function, have the same visibility as the class or function itself.

Note the difference between the protected modifier in Java and Kotlin. In Java, protected members can be accessed from the same package, but kotlin does not. In Kotlin, its members are only visible in the class and its subclasses

Note that the extension functions of the class do not have access to its private and protected members

Kotlin’s visibility modifier and Java

Kotlin’s public, protected, and private modifiers are retained when codified into Java bytecode. The only exception is private classes: this case is compiled into package private declarations.

A module usually consists of multiple packages, and different modules may contain declarations from the same package, so the internal qualifier becomes public in bytecode, which explains why it’s sometimes possible to access things from Java code that you can’t access from Kotlin

The internal member name of the class will be corrupted

In Kotlin an external class cannot see the private members of its inner/nested classes

Inner and nested classes: The default is nested classes

In Kotlin you can declare a class in another class, which is useful when encapsulating a helper class or putting some code close to where it will be used. But unlike Java, Kotlin’s nested classes cannot access instances of external classes unless you specifically ask them to.

Example declares a view that contains serializable state



So you can see that we’re trying to return a ButonState that implements the State interface, which works in Kotlin, which in Java would give an error,The ButtonState class implicitly stores a reference to its external MyButton in JavaMyButton cannot be serialized, and its reference breaks the serialization of ButtonState. To fix it, declare the ButtonState class static, and the nested class removes implicit references to the enclosing class. A nested class without explicit modifiers in Kotlin is the same as a static nested class in Java. To turn it into an inner class that holds a reference to an outer class, useinnerThe modifier

Class A is declared in another class B In Java In the Kotlin
Nested classes (do not store references to external classes) static class A class A
Inner class (stores references to external classes) class A inner class A

The syntax for referring to an external class instance in Kotlin is also different from That in Java, requiring access to the Outer class from the Inner class with this@Outer

Sealed class: Defines a restricted class inheritance structure

Review the example in kotlin’s Foundation chapter



While it is convenient to handle all possible subclasses in the WHEN expression, you must provide an else branch to handle cases where no other branch matches. It’s inconvenient to always have to add a default branch, and more importantly, if you add a new subclass, the compiler won’t notice that anything has changed, and if you forget to add a new branch, you’ll get bugs.

Kotlin provides a solution for this: sealed class.

Add the sealed modifier to the parent class to set a strict limit on the subclasses that can be created. All direct subclasses must be nested within the parent class



Sealed classes cannot have subclasses outside of the class. If you handle all of the sealed subclasses in the WHEN expression, there is no need to provide a default branch. The class implied by the sealed modifier is an open class, and you no longer need to explicitly add the open modifier.

We cannot declare the sealed interface because the compiler cannot guarantee that no one can implement this interface in Java code

In kotlin1.0, sealed is quite strict, all subclasses must be nested, and subclasses cannot be created as data classes. In 1.1, these restrictions are lifted and a subclass of Sealed can be defined anywhere in the same file