Bob Lee Course Part 13 (lectures 21 to 23)

Back to Bob! I have genuinely missed learning new information, having spent a few days doing my mega consolidation project! The will be updated at the end of each 'stage' or mini stage. So my aim now is to complete the rest of this chapter, then I will do a consolidation review of the entire chapter - object oriented Swift. OK, let's get stuck in!

Start Time - 17:02

Override Method, Init, Property









SO this is what we will be looking at - the super.viewDidLoad bit...

I get the idea of the override method. If you have a function with a class, then in the subclass, you want to change how the method works. So you need to use the override keyword.

Bob makes the point that if you use the original value of what is returned, then you need to use the super keyword...











Xcode doing an update so am screenshotting rather than typing out actual code.

All the above is fine - I had forgotten that I still need to use the super bit - even if the value is not changing. I HAD thought that if I don't want to change a thing then the override bit would not be needed.

OK this took a while...


class Human {
    
    var origin: String
    
    init(origin: String) {
        self.origin = origin
    }
}

let person = Human(origin: "China")

class European: Human {
    
    var city: String
    
    init(origin: String, city: String) {
        self.city = city
        super.init(origin: origin)
        
        
    }

}

I did NOT need the override word for this at all. 

Now to test the bit from earlier:

class Vehicle {
    
    var engineNoise: String {
        return "Vroom!"
    }
}

class Ferrari: Vehicle {
    
}

let newFerrari = Ferrari()

newFerrari.engineNoise

Yes! As suspected, I would only need 'override' if I wanted to change the engineNoise.

class Tesla {
    
    var numberWheels: Int
    
    init(numberWheels: Int) {
        self.numberWheels = numberWheels
    }
}

class ModelS: Tesla {
    
    override init(numberWheels: Int) {
        super.init(numberWheels: 4)
    }

}

The key point here is that we need to use the super keyword to call the original method. 

There are other variations here:

class ModelS: Tesla {
    
    override init(numberWheels: Int) {
        super.init(numberWheels: numberWheels)
        print("This is a beautiful car!")
    }
}

So I have to set the number of Wheels but a print statement comes up. Or I could set the number of wheels to something. If I change that on initialization, then it will still use the original value - unless I change that in the super.init line (like the one above). 

Two Phase Initialization

My Take - This is something I've heard of but I don't think I've ever actually done it before. So something new!

struct NuclearRocket {
    var metres: Double
    var litres: Double
    
}

Now Bob has used this as the example. However, the init code he has put in is unnecessary - structs don't need separate init code! 

struct NuclearRocket {
    var metres: Double
    var litres: Double
    
    init(feet: Double, gallons: Double) {
        let convertedMetres = feet * 3.28
        let convertedLitres = gallons / 3.75
        
    self.init(feet: convertedMetres, gallons: convertedLitres)
        
    }
}

Right so now I've got init in and I CAN'T just use the standard init of metres and litres...SO I do need the original all along!

Here we go...


struct NuclearRocket {
    var metres: Double
    var litres: Double
    
    init(metres: Double, litres: Double) {
        self.metres = metres
        self.litres = litres
    }
    
    init(feet: Double, gallons: Double) {
        let convertedMetres = feet * 3.28
        let convertedLitres = gallons / 3.75
        
    self.init(feet: convertedMetres, gallons: convertedLitres)
        
    }
}

So now I have two different inits to choose from. A question that comes to mind is why not use convenience in the second init? OK convenience is not used in structs! Another key point is that the convenience means that it is EASIER to create an object - most of the code is done for you. At its simplest, a convenience init is just the class and the parentheses. The above example is not actually easier at all. Cool, thanks Bob!

Type Property and Method

My Take - Well I know that type methods are ones that are called specifically within the type itself and not on the actual object created. So the keyword 'static' is used. Type properties - I think this may be where we use 'lazy' for stored properties...

struct SomeStructure {
    
    static var storedProperty = "Some value"
}

SomeStructure.storedProperty

OK I got a bit muddled with the lazy bit - that's for something else! The concept was close though!

struct SomeStructure {
    
    static var storedProperty = "Some value"
    
    static var computedProperty: Int {
        get {
            return 100
        }
        set {
            print("You have set the value to \(newValue)")
        }
    }
}

And that is where a computed property comes in. 

Bob claims that static is only for value types - structs and enums...

OK, not that - you can use static for class but also 'class' before func. So what is the difference between using static and class for func? Right, you can override class method or class property but not static. 

So coming up - the extra thing here is using 'final' - that means you cannot override too. 

Another aspect here is you can use a whole bunch of values with static in a struct:


*Just found an easier way of adding screenshots - clicked and dragged! Nice! 

SO all of that makes good sense to me. I get the difference with static, final, class etc.

All three lectures were fine - a bit of confusion with override to start with, but it came back to me. The rest of it was actually pretty logical. I have another lecture to go, but honestly, three in one go is plenty! Also, my eyes and head have been hurting after too much computer time in a day. So I'm stopping there. 

Recap:

  • When overriding a method after inheriting/subclassing, override keyword is needed as is 'super' to access and run the original init method
  • I don't need to use override if I'm just adding to the init method, rather than actually changing it (see the European example)
  • Adding in a new property does mean that that, plus any properties not initialized from before need initialisation!
  • Two phase/convenience are similar but there are clear differences. Two phase - used as init each time in structs; convenience for classes plus convenience should make the init easier (more code in the init method typically). 
  • Type methods and properties - used within the class but not in an instance/object. Static - keyword for properties/methods etc. Static cannot be overridden!
  • Class keyword used before func - these can be overridden. 
  • Final keyword used - this means it can't be inherited. 
Finish Time - 18:28 (1 hour 26 minutes)

So lots of interesting conceptual stuff here! Great to get my teeth into. Next time - one more course, then a consolidation of the chapter! 



Comments

Popular posts from this blog

*Xcode Project Entry 2* F1 Quiz - part 1

Angela Yu Course Part 10 (up to lesson 112)

Angela Yu Xcode 12 Course - Part 7 (lectures 74 to 79)