Ray Wenderlich Functions and Types Course - Part 11

OK! This is probably going to be the penultimate part. Maybe last part as I have a good hour so we'll see how far I get. Onwards with protocols!

Start Time - 17:00

Initializers

This is a pretty lengthly tutorial! Always useful to see this in action.

Installing additional Xcode components...will follow along with video without actual coding until that's ready.



So the super.init is for the superclass. That needs init.

Init phases

Phase 1- init all stored properties. From bottom of the hierarchy upwards.

Phase 2 - use anything that has the use of self.

Two phase init! Then the object is ready to use.


If you tried creating an object without declaring the value of the sports array an error would come up. So you an give a default value for that in the class....OR, much better, have another way to init!

Use of required rather than override. But required needs to be in the super class. Or the base class.

Designated inits. They need to call super.init.

So we now have the below -

required convenience init(firstName: String, lastName: String) {
        
        self.init(firstName: firstName, lastName: lastName, sports: [])
    }

So the convenience init designates the job to another designated init. You don't need to go to super.init. 

Code needs to result in a call eventually to super.init. But the convenience doesn't need to do that!

They're also great for convenient ways of instantiating an object. 

This is an interesting one!

class Student: Person {
  var grades: [String] = []
    
    convenience init(transfer: Student) {
        self.init(firstName: transfer.firstName, lastName: transfer.lastName)
        grades = transfer.grades
    }
}

With the above you have a new property - transfer, which takes on the stored properties of person, which then have to be called within the self.init bit! The grades bit is separate as this isn't done within the actual init but the values are needed....interesting!

So if there are no subclass designated inits, then these are inherited from the super class. Convenience inits are inherited too!

The whole transfer thing is tricky but I'm making sense of it. In an instance of a subclass of Student (Student Athlete), I can use that as the object within the transfer property. But the sports array is now gone as that is not in the Student/transfer bit of code. 

Polymorphism - a type is treated as the super class. 

Here's all the code - 

class Person {
  var firstName: String
  var lastName: String
  
  required init(firstName: String, lastName: String) {
    self.firstName = firstName
    self.lastName = lastName
  }
}

class Student: Person {
  var grades: [String] = []
    
    convenience init(transfer: Student) {
        self.init(firstName: transfer.firstName, lastName: transfer.lastName)
        grades = transfer.grades
    }
}

class StudentAthlete: Student {
    var sports: [String]
    
    required convenience init(firstName: String, lastName: String) {
        
        self.init(firstName: firstName, lastName: lastName, sports: [])
    }
    
    convenience init(transfer: StudentAthlete) {
        self.init(firstName: transfer.firstName, lastName: transfer.lastName, sports: transfer.sports)
        grades = transfer.grades
    }
    
    init(firstName: String, lastName: String, sports: [String]) {
        self.sports = sports
        super.init(firstName: firstName, lastName: lastName)
        
    }
    

}

let dwayne = StudentAthlete(firstName: "Daniel", lastName: "Ruettiger", sports: ["Rugby", "Checkers"])

StudentAthlete(transfer: dwayne)

let steve = StudentAthlete(transfer: dwayne)

steve.sports


A point about designated inheritance - it does so from direct superclass above. Not skipped to the next one. Super.init() is used here. 

Convenience must call within the same class! So not to the superclass. That makes sense. 

Convenience must eventually call up a designated init. 

Tricky stuff but I'm getting the concepts. 

Challenge!

Got most of this but last bit not quite right....


I was close!


class Animal {
    var name: String
    
    required init (name: String) {
        self.name = name
    }
    
    func speak() {
        
    }
}
/*:
 Create a class named `Dog` that…
 1. inherits from `Animal`
 2. has a property that stores how many tricks it has learned
 3. implements the required initializer, defaulting the trick count to `0`, and calling `speak()` at the end
 4. overrides the function `speak()` to greet you and says its name
 */

// TODO: Write solution here

class Dog: Animal {
    
    var tricksCount: Int
    
    required init(name: String) {
        tricksCount = 0
        super.init(name: name)
        speak()
        
    }
    
    override func speak() {
        print("Hello! It's \(name)")
    }
}

var george = Dog(name: "George")



Oh there's more...

Phew! Got there in the end with a bit of help in the video. 

class Dog: Animal {
    
    var tricksCount: Int
    
    required init(name: String) {
        tricksCount = 0
        super.init(name: name)
        speak()
        
    }
    
    init(name: String, tricksCount: Int) {
        self.tricksCount = tricksCount
        super.init(name: name)
        speak()
        
    }
    
    convenience init(tricksCount: Int = Int.max) {
        self.init(name: "George", tricksCount: tricksCount)
    }
    
    
    override func speak() {
        print("Hello! It's \(name)")
    }
}


Last bit for now...

Protocols

Animal in our example is not meant to be instantiated - it's assumed that there will be subclasses - like dog we just did. 

In protocols you are specifying the REQUIREMENTS, not any instantiation. Makes sense! You can specify get and - if needed - set. 

To conform to a protocol means satisfying ALL of its requirements. 

Lots of cool stuff here! Advantages are that the protocol itself are simple. But you can't use polymorphism when creating an array of types that both inertia from the same protocol. Not inherit, but conform to the same protocol! You would have to specify 'Animal' in square brackets for that. 

OK that will do for now. Phew!

Finish Time - 18:02 (1 hour)

A great refresher on initialisation and a bit on protocols too. Tomorrow I will complete this course, then start doing consolidation - that may take two entries in itself! Lots of useful stuff in this course but it is definitely time to look for the next one! Catie's has been one of the best, honestly loads of good stuff from here. The great thing with rw.com is that there is new content added regularly - much better than Udemy, Treehouse or anything else, in terms of an overall site to use. Still, Angela Yu's projects have been where I have learned the most!


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)