fbelfort
fbelfort

Reputation: 293

Initializer with self.variable = variable

I'm new to Swift. I don't understand what's the purpose of self.seconds = seconds in the following example:

class Time {
    var seconds:Double = 0

    init(seconds: Double) {
        self.seconds = seconds
    }

    var minutes: Double {
        get {
            return (seconds / 60)
        }
        set {
            self.seconds = (newValue * 60)
        }
    }

    var hours: Double {
        get {
            return (seconds / (60 * 60))
        }
        set {
            self.seconds = (newValue * (60 * 60))
        }
    }
}

According to xcode 'self.seconds' is a variable and 'seconds' is a let constant. I'm confused. Any thoughts ?

Upvotes: 1

Views: 411

Answers (4)

shallowThought
shallowThought

Reputation: 19602

If you instantiate Time the init method is called. var seconds:Double = 0 defines a default value.

let time = Time()  //calls init(). time has default value of zero seconds

If you call one of the parametrized init methods the default value gets overridden:

let time = Time(seconds: 42.0) //calls init(seconds: Double). time has been initialized with 42 seconds

Upvotes: 0

vadian
vadian

Reputation: 285079

You have three options when passing a non-optional parameter:

  • You declare the property with a default value and overwrite it in init (not recommended):

    var seconds : Double = 0.0 // or even var seconds = 0.0 (the compiler infers the Double type)
    
    init(seconds: Double) {
        self.seconds = seconds
    }
    
  • You declare the property and assign the default value in init:

    var seconds : Double
    
    init(seconds: Double) {
        self.seconds = seconds
    }
    
  • You declare the property as constant (read only) and assign the value in init

    let seconds : Double
    
    init(seconds: Double) {
        self.seconds = seconds
    }
    

In any case self.seconds represents the property and seconds the passed parameter.

Upvotes: 0

silicon_valley
silicon_valley

Reputation: 2689

When you initialize a Time object, you store the seconds you pass in as an argument into the member variable (also called seconds). You can imagine if you had another initializer for minutes or hours, it would convert the minutes or hours and then store them as seconds. So for example:

class Time {
    var seconds:Double = 0

    init(seconds: Double) {
        self.seconds = seconds
    }

    init(minutes: Double) {
        self.seconds = minutes * 60
    }

    init(hours: Double) {
        self.seconds = hours * 60 * 60
    }

    var minutes: Double {
        get {
            return (seconds / 60)
        }
        set {
            self.seconds = (newValue * 60)
        }
    }

    var hours: Double {
        get {
            return (seconds / (60 * 60))
        }
        set {
            self.seconds = (newValue * (60 * 60))
        }
    }
}

Just because the parameter has the same name as the Time object's variable, doesn't mean it automatically contains the same value.

Upvotes: 0

FelixSFD
FelixSFD

Reputation: 6092

In the scope of you initializer, you have one local constant seconds and a variable property seconds (which you are accessing with self.seconds to avoid confusions).

To make it less confusing, you could rename the parameter of your initializer to something like newSeconds.

init(seconds newSeconds: Double) {
    self.seconds = newSeconds
}

This doesn't change how you call the initializer (you still use the label seconds:, but your initializer is less confusing.

Upvotes: 1

Related Questions