Classes and Structs - interim Practice!
So I was all ready to move onto the next course but really feel the need to crack the whole initialiser (which is one of the most difficult words to type by the way!) thing first. It makes more sense to have a little more practice with this! So for the first time since going back to Treehouse, I'm veering away from it - albeit briefly...
First stop - the Apple Developer Guidance
Structures and classes are general-purpose, flexible constructs that become the building blocks of your program’s code. You define properties and methods to add functionality to your structures and classes using the same syntax you use to define constants, variables, and functions.
Straight from the text! All of that makes sense. Pasan also referred to them as 'Objects'. Ah hang on, that's an instance of a construct.
Again, from the text, here is what both Structures and Classes can do:
I don't in all honesty understand ALL of this but get the general idea. They both basically bundle together values, have initial values (though classes need these made explicit), class is a reference; structure is a value...that's what I've got for now!
Now I want to look specifically at initialisation...
Initialization is the process of preparing an instance of a class, structure, or enumeration for use. This process involves setting an initial value for each stored property on that instance and performing any other setup or initialization that is required before the new instance is ready for use.
OK, so it is needed for the instance of a class/structure - for an object. The next bit to clarify is the customisation of init values...
The next bit of this is rather technical. I'm going to switch texts/information now to clarify the whole point of initialisation - how it works specifically for classes and subclasses...
https://www.raywenderlich.com/119922/swift-tutorial-initialization-part-1
This is what I've found! I've actually purchased one of this courses, which I will use at some point over the summer.
So in the two examples above, the first struct has initialiser values put in. That means when creating an instance, just the () - no custom values are used. In the second one, one set value (the nominalBurnTime) is there, but the other two values need to be chosen - they are custom initialiser values.
*This seems to be more for structs...let's find one more for classes!
That's all straightforward, as the class has to have the initialisers in.
First stop - the Apple Developer Guidance
Structures and classes are general-purpose, flexible constructs that become the building blocks of your program’s code. You define properties and methods to add functionality to your structures and classes using the same syntax you use to define constants, variables, and functions.
Straight from the text! All of that makes sense. Pasan also referred to them as 'Objects'. Ah hang on, that's an instance of a construct.
Again, from the text, here is what both Structures and Classes can do:
- Define properties to store values
- Define methods to provide functionality
- Define subscripts to provide access to their values using subscript syntax
- Define initializers to set up their initial state
- Be extended to expand their functionality beyond a default implementation
- Conform to protocols to provide standard functionality of a certain kind
Classes have additional capabilities that structures don’t have:
- Inheritance enables one class to inherit the characteristics of another.
- Type casting enables you to check and interpret the type of a class instance at runtime.
- Deinitializers enable an instance of a class to free up any resources it has assigned.
- Reference counting allows more than one reference to a class instance.
I don't in all honesty understand ALL of this but get the general idea. They both basically bundle together values, have initial values (though classes need these made explicit), class is a reference; structure is a value...that's what I've got for now!
Now I want to look specifically at initialisation...
Initialization is the process of preparing an instance of a class, structure, or enumeration for use. This process involves setting an initial value for each stored property on that instance and performing any other setup or initialization that is required before the new instance is ready for use.
OK, so it is needed for the instance of a class/structure - for an object. The next bit to clarify is the customisation of init values...
The next bit of this is rather technical. I'm going to switch texts/information now to clarify the whole point of initialisation - how it works specifically for classes and subclasses...
https://www.raywenderlich.com/119922/swift-tutorial-initialization-part-1
This is what I've found! I've actually purchased one of this courses, which I will use at some point over the summer.
struct RocketConfiguration {
let name: String = "Athena 9 Heavy"
let numberOfFirstStageCores: Int = 3
let numberOfSecondStageCores: Int = 1
}
struct RocketStageConfiguration {
let propellantMass: Double
let liquidOxygenMass: Double
let nominalBurnTime: Int = 100
}
let newRocket = RocketStageConfiguration(propellantMass: 7.6, liquidOxygenMass: 2.2)
So in the two examples above, the first struct has initialiser values put in. That means when creating an instance, just the () - no custom values are used. In the second one, one set value (the nominalBurnTime) is there, but the other two values need to be chosen - they are custom initialiser values.
*This seems to be more for structs...let's find one more for classes!
class UserNew {
var name: String = ""
var age: Int = 0
init (name: String, age: Int) {
self.name = name
self.age = age
}
}
let newName = UserNew(name: "Steve", age: 34)
class SpecialUserNew: UserNew {
var greetingMessage: String
init (name: String, age: Int, greetingMessage: String) {
self.greetingMessage = greetingMessage
super.init(name: name, age: age)
}
override func sayHi() -> String {
return "\(greetingMessage) \(name)"
}
}
In this example, I did not need to put in 'override' for the init bit...not actually sure why!
https://theswiftdev.com/2017/10/10/swift-4-init-patterns/
This link clarifies something about initialisers in structs. These are called 'member wise' initialisers. Structs don't need to have init made explicit whereas classes do. I get now that the reason you would do init with structs if you didn't want access to ALL of the properties. That makes more sense!
Something else clarified is that class initialisers are generated for free if values are assigned to them; in that case, you don't need to do the init process. However, most of the time you do!
There are two rules of init inheritance:
If your subclass doesn’t define any designated initializers, it automatically inherits all of its superclass designated initializers.
If your subclass provides an implementation of all of its superclass designated initializers—either by inheriting them as per rule 1, or by providing a custom implementation as part of its definition—then it automatically inherits all of the superclass convenience initializers.
So I found something out about override - you use that if what you're creating is identical in terms of the initial values.
lass Animal {
var size: Double
var habitat: String
var carnivore: Bool
init(size: Double, habitat: String, carnivore: Bool) {
self.size = size
self.habitat = habitat
self.carnivore = carnivore
}
}
let newAnimal = Animal(size: 34.2, habitat: "Forest", carnivore: true)
newAnimal.habitat
I've just created this, so I can see what happens with the subclass...
class Dog: Animal {
var breed: String
init(size: Double, habitat: String, carnivore: Bool, breed: String) {
self.breed = breed
super.init(size: size, habitat: habitat, carnivore: carnivore)
}
}
let newDog = Dog(size: 55, habitat: "House", carnivore: true, breed: "Beagle")
OK, something clarified here is that the override keyword is used if the parameters do NOT change in the subclass. In the above example, override was not needed; in the below one it was...
class Dog: Animal {
override init(size: Double, habitat: String, carnivore: Bool) {
super.init(size: size, habitat: habitat, carnivore: carnivore)
}
}
But now this subclass is identical to the superclass - no point in doing so. I can still put in stored properties, but not as parameters, unless I change the init code. OK, makes more sense - what's put in the first init part is what parameters are needed altogether. What is then put in the super init part is specifically from the superclass.
That has clarified things a bit - still some work to do but the idea of the inits, parameters, sub and super don't seem too daunting now! Next time it will be on with the next course...!
Comments
Post a Comment