Kotlin in Action Review Points

Chapter 4

  • Interfaces in Kotlin are similar to Java’s but can contain default implementations and properties.
  • All declarations are final and public by default.
  • To make a declaration no-final, mark it as open.
  • internal declarations are visible in the same module.
  • Nested classes aren’t inner by default. Use the keyword inner to store a reference to an outer class.
  • A sealed class can only have subclasses nested in its declaration.
  • Initializer blocks and secondary constructors provide flexibility for initializing class instances.
  • You use the field identifier to reference a property backing field from the accessor body.
  • Data classes provide compile-genereated equals(), hashCode(), toString(), copy(), and other methods.
  • Class delegation helps to avoid many similar delegating methods in your code.
  • Object declaration is Kotlin’s way to define a singleton class.
  • Companion objects(along with package-level functions and properties) replace Java’s static methods and field definitions.
  • Companion objects, like other objects, can implement interfaces or have extension functions or properties.
  • Object expressions are Kotlin’s replacement for Java’s anonymous inter classes, with added power such as the ability to implement multiple interfaces and to modify the variables defined in the scope where the object is created.

Chapter 5

  • Lambdas allow you to pass chunks of code as parameters to methods.
  • Kotlin lets you pass lambdas to methods outside of parentheses and refer to a single lambda parameter as it.
  • Code in a lambda can access and modify variables in the function containing the call to the lambda.
  • You can create references to methods, constructors, and properties by prefixing the name of the function with ::, and pass such references to methods instead of lambdas.
  • Most common operations with collections can be performed without manually iterating over elements, using functions such as filter, map, all, any, and so on.
  • Sequences allow you to combine multiple operations on a collection without creating collections to hold intermediate results.
  • You can pass lambdas as arguments to methods that take a Java functional interface ( an interface with a single abstract methods, also known as SAM interface) as a parameter.
  • Lambdas with receivers are lambdas in which you can directly call methods on a special receiver object.
  • The with standard library function allows you to call multiple methods on the same object without repeating the reference to the object. apply lets you construct and initialize any object using a builder-style API.

Chapter 6

  • Kotlin’s support of nullable types detects possible NullPointerException errors at compile time.
  • Kotlin provides tools such as safe calls(?.), the Elvis operator(?:), not-null assertions(!!), and the let function for dealing with nullable types concisely.
  • The as? operator provides an easy way to cast a value to a type and to handle the case when it has a different type.
  • Types coming from Java are interpreted as platform types in Kotlin, allowing the developer to treat them as either nullable or non-null.
  • Types representing basic numbers (such as Int?) correspond to boxed primitive types in Java(such as java.lang.Integer).
  • The Any type is a supertype of all other typess and is analogous to Java’s Object. Unitis an analogue of void.
  • The Nothing type is used as a return type of functions that don’t terminate normally.
  • Kotlin uses the standard Java classes for collections and enhances them with a distinction between read-only and mutable collections.
  • You need to carefully consider nullability and mutability of parameters when you extend Java classes or implement Java interfaces in Kotlin.
  • Kotlin’s Array class looks like a regular generic class, but it’s compiled to a Java array.
  • Arrays of primitive types are represented by special classes such as Intarray.

Chapter 7

  • Kotlin allows you to overload some of the standard operations by defining functions with the corresponding names, but you can’t define your own operators.
  • Comparison operators are mapped to calls of equals and compareTo methods.
  • By defining functions named get, set, and contains, you can support the [] and in operators to make your class similar to Kotlin collections.
  • Creating ranges and iterating over collections also work through conventions and arrays.
  • Destructuring declarations let you initialize multiple variables by unpacking a single object, which is handy for returning multiple values from a function. They work with data classes automatically, and you can support them for your own classes by defining
    functions named componentN().
  • Delegated properties allow you to reuse logic controlling how property values are stored, initialized, accessed, and modified, which is a powerful tool for building frameworks.
  • The lazy standard library function provides an easy way to implement lazily initialized properties.
  • The Delegates.observable function lets you add an observer of property changes.
  • Delegated properties can use any map as a property delegate, providing a flexible way to work with objects that have variable sets of attributes.

Chapter 8

  • Function types allow you to declare a variable, parameter, or function return value that holds a reference to a function.
  • Higher-order functions take other functions as arguments or return them. You can create such functions by using a function type as the type of a function parameter or return value.
  • When an inline function is compiled, its bytecode along with the bytecode of a lambda passed to it is inserted directly into the code of the calling function, which ensures that the call happens with no overhead compared to similar code written directly.
  • Higher-order functions facilitate code reuse within the parts of a single component and let you build powerful generic libraries.
  • Inline functions allow you to use non-local returns—return expressions placed in a lambda that return from the enclosing function.
  • Anonymous functions provide an alternative syntax to lambda expressions with different rules for resolving the return expressions. You can use them if you need to write a block of code with multiple exit points.

Chapter 9

  • Kotlin’s generics are fairly similar to those in Java: you declare a generic function or class in the same way.
  • As in Java, type arguments for generic types only exist at compile time.
  • You can’t use types with type arguments together with the is operator, because type arguments are erased at runtime.
  • Type parameters of inline functions can be marked as reified, which allows you to use them at runtime to perform is checks and obtain java.lang.Class instances.
  • Variance is a way to specify whether the type parameter of a type can be substitued for its subclass or superclass.
  • You can declare a class as covariant on a type parameter if the parameter used only in out positions.
  • The oppsite is ture for contravariant cases: you can declare a class as contravariant on a type parameter if it’s used only in in positions.
  • The read-only interface List in Kotlin is declared as covariant, which means List<String> is a subtype of List<Any>.
  • The function interface is declared as contravariant on its first type parameter and covariant on its seconds, which makes (Animal) -> Int a subtype of (Cat) -> Number.
  • Kotlin lets you specify variance both for a generic class as a whole (declaration-site variance).
  • The start-projection syntax can be used when the exact type arguments are unknown or unimportant.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章