Kotlin
Classes and Inheritance
Swift
|
Classes
|
class Invoice { /*...*/ }
|
class Invoice { /*...*/ }
|
class Empty
|
class Empty {}
|
Constructors
|
class Person constructor(firstName: String) { /*...*/ }
|
class Person {
init(firstName: String) {}
/*...*/
}
|
class Person(firstName: String) { /*...*/ }
|
class Person {
init(firstName: String) { /*...*/ }
}
|
class InitOrderDemo(name: String) {
val firstProperty = "First property: $name".also(::println)
init {
println("First initializer block that prints ${name}")
}
val secondProperty = "Second property: ${name.length}".also(::println)
init {
println("Second initializer block that prints ${name.length}")
}
}
👏
|
class InitOrderDemo {
private let name: String
init(name: String) {
self.name = name
print("First initializer block that prints \(name)")
}
var firstProperty: String {
get {
return "First property: \(self.name)"
}
}
var secondProperty: String {
get {
return "Second property: \(self.name.count)"
}
}
}
|
class Customer(name: String) {
val customerKey = name.toUpperCase()
}
|
class Customer {
private let name: String
init(name: String) {
self.name = name
}
var customerKey: String {
get { return name.toUpperCase }
}
}
|
class Person(val firstName: String, val lastName: String, var age: Int) { /*...*/ }
|
class Person {
let firstName, lastName: String
var age: Int
init(firstName: String, lastName: String, age: Int){
self.firstName = firstName
self.lastName = lastName
self.age = age
}
/*...*/
}
|
class Person(
val firstName: String,
val lastName: String,
var age: Int, // trailing comma
) { /*...*/ }
|
|
class Customer public @Inject constructor(name: String) { /*...*/ }
|
|
Secondary constructors
|
class Person {
var children: MutableList<Person> = mutableListOf()
constructor(parent: Person) {
parent.children.add(this)
}
}
|
class Person {
var children: [Person] = []
init(parent: Person) {
parent.children.append(self)
}
}
|
class Person(val name: String) {
var children: MutableList<Person> = mutableListOf()
constructor(name: String, parent: Person) : this(name) {
parent.children.add(this)
}
}
|
class Person {
let name: String
var children: [Person] = []
init(name: String) {
self.name = name
}
convenience init(name: String, parent: Person) {
self.init(name: name)
parent.children.append(self)
}
}
|
class Constructors {
init {
println("Init block")
}
constructor(i: Int) {
println("Constructor")
}
}
|
class Constructors {
init() {
print("Constructor in default")
}
convenience init(i: Int) {
print("Constructor with \(i)")
}
}
|
class DontCreateMe private constructor () { /*...*/ }
|
class DontCreateMe {
private init() { }
/*...*/
}
|
class Customer(val customerName: String = "")
|
class Customer {
let customerName: String
init(customerName: String = "") {
self.customerName = customerName
}
}
|
Creating instances of classes
|
val invoice = Invoice()
val customer = Customer("Joe Smith")
|
let invoice = Invoice()
let customer = Customer("Joe Smith")
|
Inheritance
|
class Example // Implicitly inherits from Any
|
Swift classes do not inherit from a universal base class.
|
open class Base //Class is open for inheritance
|
class Base //Class is default open for inheritance
|
open class Base(p: Int)
class Derived(p: Int) : Base(p)
|
class Base {
init(p: Int) {}
}
class Derived: Base {}
|
class MyView : View {
constructor(ctx: Context) : super(ctx)
constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs)
}
|
class MyView: View {
override init(ctx: Context) {
super.init(ctx: ctx)
}
override init(ctx: Context, attrs: AttributeSet) {
super.init(ctx: ctx, attrs: attrs)
}
}
|
Overriding methods
|
open class Shape {
open fun draw() { /*...*/ }
fun fill() { /*...*/ }
}
class Circle() : Shape() {
override fun draw() { /*...*/ }
}
|
class Shape {
func draw() { /*...*/ }
private func fill() { /*...*/ }
}
class Circle: Shape {
override func draw() { /*...*/ }
}
|
open class Rectangle() : Shape() {
final override fun draw() { /*...*/ }
}
|
class Rectangle: Shape {
final override func draw() { /*...*/ }
}
|
Overriding properties
|
open class Shape {
open val vertexCount: Int = 0
}
class Rectangle : Shape() {
override val vertexCount = 4
}
|
class Shape {
var vertexCount: Int = 0
}
class Rectangle: Shape {
override init() {
super.init()
vertexCount = 4
}
}
|
interface Shape {
val vertexCount: Int
}
class Rectangle(override val vertexCount: Int = 4) : Shape // Always has 4 vertices
class Polygon : Shape {
override var vertexCount: Int = 0 // Can be set to any number later
}
|
protocol Shape {
var vertexCount: Int { get }
}
class Rectangle: Shape {
let vertexCount: Int = 4
}
class Polygon : Shape {
var vertexCount: Int = 0 // Can be set to any number later
}
|
Derived class initialization order
|
open class Base(val name: String) {
init { println("Initializing Base") }
open val size: Int =
name.length.also { println("Initializing size in Base: $it") }
}
class Derived(
name: String,
val lastName: String,
) : Base(name.capitalize().also { println("Argument for Base: $it") }) {
init { println("Initializing Derived") }
override val size: Int =
(super.size + lastName.length).also { println("Initializing size in Derived: $it") }
}
|
class Base {
let name: String
init(name: String) {
self.name = name
print("Initializing Base")
}
var size: Int {
get { return name.count }
}
}
class Derived: Base {
let lastName: String
init(name: String, lastName: String) {
self.lastName = lastName
print("Initializing Derived")
super.init(name: name.uppercased())
}
override var size: Int {
get { return super.size + lastName.count }
}
}
|
Calling the superclass implementation
|
open class Rectangle {
open fun draw() { println("Drawing a rectangle") }
val borderColor: String get() = "black"
}
class FilledRectangle : Rectangle() {
override fun draw() {
super.draw()
println("Filling the rectangle")
}
val fillColor: String get() = super.borderColor
}
|
class Rectangle {
func draw() { print("Drawing a rectangle") }
var borderColor: String {
get { "black" }
}
}
class FilledRectangle: Rectangle {
override func draw() {
super.draw()
print("Filling the rectangle")
}
var fillColor: String {
get { super.borderColor }
}
}
|
class FilledRectangle: Rectangle() {
override fun draw() {
val filler = Filler()
filler.drawAndFill()
}
inner class Filler {
fun fill() { println("Filling") }
fun drawAndFill() {
super@FilledRectangle.draw() // Calls Rectangle's implementation of draw()
fill()
println("Drawn a filled rectangle with color ${super@FilledRectangle.borderColor}") // Uses Rectangle's implementation of borderColor's get()
}
}
}
|
class Rectangle {
func draw() { print("Rectangle")/* ... */ }
}
protocol Polygon {
func draw()
}
extension Polygon {
func draw() { print("Polygon")/* ... */ }
}
class Square: Rectangle, Polygon {
// The compiler requires draw() to be overridden:
override func draw() {
super.draw() // call to Rectangle.draw()
}
}
|
Overriding rules
|
open class Rectangle {
open fun draw() { /* ... */ }
}
interface Polygon {
fun draw() { /* ... */ } // interface members are 'open' by default
}
class Square() : Rectangle(), Polygon {
// The compiler requires draw() to be overridden:
override fun draw() {
super<Rectangle>.draw() // call to Rectangle.draw()
super<Polygon>.draw() // call to Polygon.draw()
}
}
|
class Rectangle {
func draw() { print("Rectangle")/* ... */ }
}
protocol Polygon {
func draw()
}
extension Polygon {
func draw() { print("Polygon")/* ... */ }
}
class Square: Rectangle, Polygon {
// The compiler requires draw() to be overridden:
override func draw() {
super.draw() // call to Rectangle.draw()
}
}
|
Abstract classes
|
open class Polygon {
open fun draw() {}
}
abstract class Rectangle : Polygon() {
abstract override fun draw()
}
|
|