Hi, I'm Ataias Reis

Programmer, made in Brazil, Alma mater University of Brasilia

30 days of code in Go: Day 12 - Inheritance (kind of)

Inheritance is a nice concept that object-oriented languages have. It is basically the ability for one type, many times called a class or even a struct depending on the language, to inherit the behaviour of another type.

HackerRank doesn’t allow me, at least at the moment this post is being written, to submit code in Go for this challenge of inheritance. It seems like Go doesn’t support inheritance, though there are some workarounds that let us mimic the behaviour. The code below is what I tested to mimic the behaviour of a Student class that inherits from the Person class. The Student class has a different printPerson method that calls its super method (the method of the parents class) and it also inherits the sayHello function which is just called by the Student instance object.

package main

import "fmt"

type Personilizer interface {
  printPerson()
  sayHello()
}

type Person struct {
  FirstName string
  LastName  string
  Id        int
}

func (a Person) printPerson() {
  fmt.Printf("Name: %s, %s\nID: %d\n",
    a.LastName, a.FirstName, a.Id)
}

func (a Person) sayHello() {
  fmt.Printf("Hello!")
}

type Student struct {
  //anonymous field Person
  // after the code I will explain
  // how this works
  Person
  scores []float64
}

func (a Student) printPerson() {
  a.Person.printPerson()
  fmt.Printf("Grade: %s\n", a.calculate())

}

func (a Student) calculate() string {
  average := 0.0
  total := float64(len(a.scores))
  for i := 0; i < len(a.scores); i++ {
    average += a.scores[i] / total
  }

  if average >= 90 {
    return "O"
  } else if average >= 80 {
    return "E"
  } else if average >= 70 {
    return "A"
  } else if average >= 55 {
    return "P"
  } else if average >= 40 {
    return "D"
  }

  return "T"
}

func main() {
  var firstName string
  var lastName string
  var id int
  var numScores int
  var scores []float64
  fmt.Scanf("%s %s %d\n",
    &firstName, &lastName, &id)
  fmt.Scanf("%d", &numScores)
  scores = make([]float64, numScores)
  for i := 0; i < numScores; i++ {
    fmt.Scanf("%f", &scores[i])
  }

  a := new(Student)
  a.FirstName = firstName
  a.LastName = lastName
  a.Id = id
  a.scores = scores

  a.printPerson()
  // sayHello was only defined for person,
  // but it works here
  a.sayHello()
}

Input/output example:

$ go build day_12.go
$ ./day_12          
# input
Fulano deTal 1234
2
1 2
# output
Name: deTal, Fulano
ID: 1234
Grade: T
Hello!

An anonymous field is a really interesting concept in Go. It is a field with no name, just the type, that allow us to access its members as if they were from the class that has the anonymous field 1. This is what really allow us to mimic inheritance behaviour.

That’s all for today! Thanks for reading! If you have any comments, suggestions or critics, let me know!

Tags
comments powered by Disqus