Skip to content

Latest commit

 

History

History
249 lines (194 loc) · 6.25 KB

03-interfaces.md

File metadata and controls

249 lines (194 loc) · 6.25 KB

Lab: Interfaces

Take me to the lab!

Help for the VSCode editor.

  1. Select the correct declarations for an interface.
    1. type Student interface {
          id int
          grades  []int
          func calcGrades()
      }
    2. type Student interface {
          calcGrades()
          getName()
      }
    3. type Employee interface {
          calcSalary()
          getName()
      }
    4. type Employee interface {
          func calcSalary()
          func getName()
      }
    Reveal

    B, C

    • A is incorrect because interfaces cannot have fields, only methods.
    • D is incorrect because the func keyword is not used on interface method declarations.
  2. What would be the output of the following program?

    Note: add package and import statements as needed

    type Student interface {
        getPercentage() int
        getName()
    }
    
    type Undergrad struct {
        name   string
        grades []int
    }
    
    func (u Undergrad) getPercentage() int {
        sum := 0
        for _, v := range u.grades {
            sum += v
        }
        return sum / len(u.grades)
    }
    
    func printPercentage(s Student) {
        fmt.Println(s.getPercentage())
    }
    
    func main() {
        grades := []int{90, 75, 80}
        u := Undergrad{"Ross", grades}
        printPercentage(u)
    }
    • No output
    • Error
    • 81
    • 81%
    Reveal

    Error

    • There is a bug in this program. It will fail to compile due to the last line which will produce the error Undergrad does not implement Student (missing getName method)
    • When a struct value is passed as an argument to a function that has an interface parameter, the struct's implementation will be checked by the compiler.
    • Undergrad has a receiver for getPercentage but not for getName therefore it is an incomplete implementation of the interface Student.
  3. What would be the output of the following program?

    Note: add package and import statements as needed

    type Student interface {
        getPercentage() int
        getName() string
    }
    
    type Undergrad struct {
        name   string
        grades []int
    }
    
    func (u Undergrad) getPercentage() int {
        sum := 0
        for _, v := range u.grades {
            sum += v
        }
        return sum / len(u.grades)
    }
    func (u Undergrad) getName() string {
        return u.name
    }
    
    func printData(s Student) {
        fmt.Println(s.getName())
        fmt.Println(s.getPercentage())
    }
    
    func main() {
        grades := []int{90, 75, 80}
        u := Undergrad{"Ross", grades}
        printData(u)
    }
    • No output
    • Ross
      81
    • Error
    • 81
      Ross
    Reveal

    Ross
    81

    • The bug from Q2 has been fixed. An implementation has been provided for getName, so no error.
    • No output is incorrect because the two Println statements in the printData function will be executed.
    • While we're there, note that the name will be printed first, so that eliminates another answer.
    • Finally, getPercentage calculates the average of all the grades in the grades slice. The calculation is using integer math, hence 81. No percent sign is printed.
  4. What would be the output of the following program?

    Note: add package and import statements as needed

    type Student interface {
        getPercentage() int
        getName() string
    }
    
    type Undergrad struct {
        name   string
        grades []int
    }
    
    type Postgrad struct {
        name   string
        grades []int
    }
    
    func (p Postgrad) getPercentage() int {
        sum := 0
        for _, v := range p.grades {
            sum += v
        }
        return ((sum * 100) / (len(p.grades) * 200))
    }
    func (p Postgrad) getName() string {
        return p.name
    }
    
    func (u Undergrad) getPercentage() int {
        sum := 0
        for _, v := range u.grades {
            sum += v
        }
        return sum / len(u.grades)
    }
    
    func (u Undergrad) getName() string {
        return u.name
    }
    
    func printData(s Student) {
        fmt.Println(s.getName())
        fmt.Println(s.getPercentage())
    }
    
    func main() {
        u := Undergrad{"Ross", []int{90, 75, 80}}
        p := Postgrad{"Joe", []int{150, 190, 185}}
        printData(u)
        printData(p)
    }
    • Ross 81
      Joe 87
    • Joe 87
      Ross 81
    • Ross
      81
      Joe
      87
    • Ross
      Joe
      81
      87
    Reveal

    Ross
    81
    Joe
    87

    • Now there is a new struct Postgrad. Postgrad correctly implements the Student interface as it has correct receivers for getName and getPercentage.
    • Note that the getPercentage for Postgrad is a different implementation, i.e. the percentage is calculated differently.
    • The function printData is the same as in Q3, therefore from that we know the order in which it will print the student data (name, newline, percentage). This eliminates two answers. It also eliminates a third because it won't output two names followed by two percentages.
  5. Which of the following keyword is used to implement an interface in Golang?
    • type struct
    • receiver
    • No keyword needed to implement an interface
    • type interface
    Reveal

    No keyword needed to implement an interface

    • Keywords are used to declare an interface, not implement it.
    • Implementation is achieved by providing all of the correct receiver methods as defined by the interface for any struct that wants to provide an implementation.