Pages

Wednesday, June 6, 2018

Learn Kotlin 9 (Classes and Inheritance3:Hi friends this is the continuation of previous post so i kindly request you to read that before this post. As this blog is also prepared for beginners so i advice you that you don't need to by-heart this lessons just read and understand it if you have any doubt ask in the comment section)

Overriding Methods

Here is an example of overriding methods
open class Base{
          open fun my(){}
          fun my2(){}
}
class Derived: Base {
 override fun my(){
//overrid here
}
}
The override annotation is required here for Derived.my and if it were missing the compiler will complain andif there is no open annotation on functions like Base.my2 then declaring a method with same signature in a subclass is illegal either with override or without it in a final class open members are prohibited a memeber marked override is itself open it may be overriden in subclasses to prohibit overriding you can use the final keyword

Properties

The properties are variables which have a class level scope and which are declared inside the class but outside the methods or functions is called as a property in kotlin these can be declared as mutable using var keyword and immutable with val keyword
class Home{
 var owner:String="alex".
var name:String="mannat"
var lane:String="pk lane"
var address:String= "is address"
}
To use a property we simply refer to it by name
fun copydetails(home:Home):Home{
val details = Home()
details.name = home.name//accessors are called to access the values
details . owner = home.owner
return details
}

Getters And Setters

The getters and setters are methods on which the getter method is used to which returns the value and setter method which sets the value for the method. a full syntax a property is declared as is
var <property name>[:<propertytype>][= <property_initializer>]
[<getter>]
[<setter>]
here the getter and setter are optional and property type is also optional if the type can be infered from the initializer or from the getter return type and for immutable variables with val keyword the setter method is not allowed
here is some examples for default getters and setters for mutable and immutable variables
var age:Int?
//error as the explicit initializer is required, default getter and setter implied
var initialize = 1//has type int default getter and setter
val ages : Int? //has type int and default getter
 

we can write custom accessors like ordinary functions inside the property declarations here is an example of a custom getter
val isEmpty: Boolean
     get() = this.size == 0
   
A custom setter looks like this
var name:String
get.this.toString()
set(value){
setDataFromString(value)
//parses the string and assigns value to other properties
}
By convention the name of the setter parameter is value but we can chose a different one if we need
and you can ignore the property type if it can be inferred from the getter if we need to change the visibility of accessor or annotate it but don't need to change the default implementation we define the accessor without defining its body like
var isEmpty get() = this.size == 0//by getter we know its type boolean
var settervisibility:String = "abc"
private set
//the setter is private and have default implementation
var setterwithannotation:Any? = null
@Inject set //annotate the setter with inject

Overriding properties

The overriding properties works similar to overriding methods were properties declared on a superclass are then redeclared on the subclass must be prefaced with override and they must have a compatible type each declared properties can be overriden by a property with an initializer or by a property with a getter method for example
open class Foo{
       open val numb:Int get(){}
}
class Bar1:Foo(){
      override val numb :Int =...
}
A val property can be overrided with a var property because the val property always declares a getter method and overriding it as a var additionally declares a setter method in the derived class ()
we can use a override keyword as part of the property declaration in a primary constructor

Interface Foo {
val count :Int
}
class Bar1(override val count: Int):Foo
class Bar2:Foo{
override var count:Int = 0
}

Derrived class Initialization Model

A point to note here is construction of new instance of a derived class the first step done is the initialization of the base class (preceded only by evaluation of the arguments for  the base class constructor ) and thus happens before the initialization logic of the derived class is run

Calling Super Class

The super class is the base class of the derived class the code in derived class can call its superclass function and property accessors implementation using the super keyword

Overriding rules

If a class inherits from many implementations of the same member from its immediate superclasses it must override this member and provide its own implementation (using one of the inherited ones ).to denote the supertype from which the inherited implementation is taken we use the super qualified by the supertype name in angle brackets eg:-super<Base>

open class A{
 fun f(){println("A")}
fun a(){println("a")}

}
interface B{
 fun f(){print("B")}//interface will be explained later
fun b(){print("b")}//interface members are open by default
}
class C :A(),B{
//the compiler requires f to be overriden
override fun f(){
super<.A>.f() //call to A.f()
super<B>.f() //call to B.f()
}
}
In here class C is both inherited from both A and B and we have no problem with function a() and b() since C inherits only one implementation of each of this function but for f() we have two implementations inherited by C and thus we have to override f() in C and provide our own implementation that eliminates ambiguity 

No comments:

Post a Comment