Rick

Rick
Rick

Monday, January 14, 2013

Java Guide to Go Programming article 3: Polymorphism

This is part three in this series. Essentially I assume you know Java and that you want to learn Go Programming. You can find article 1, and article 2 on this blog as well.

In Java method overriding is a given, and polymorphism works well. In Go Programming, it is not quite the same. For polymorphism to work in Go, you really need an interface.

Polymorphism example in GO

/examples/src/example/usePolymorphism.go
package main

import (
 "example/polymorphism"
 "fmt"
)

func main() {
 employee1 := polymorphism.NewEmployee("Rick", "Hightower", 32, true)
 employee2 := polymorphism.NewSalesEmployee("Whitney", "Hightower", 17, true, 0.05)
 employee3 := polymorphism.NewHourlyEmployee("Bob", "Hightower", 27, true, 25.0)

 employees := []polymorphism.Payable{employee1, employee2, employee3}

 for _, employee := range employees {
  fmt.Printf("%s %2.2f \n", employee.Name(), employee.CalculatePay())
 }

}

Polymorphism example in Java

/java-examples/src/com/example/UsePolymorphism.java
package com.example;

import com.example.polymorphism.Employee;
import com.example.polymorphism.HourlyEmployee;
import com.example.polymorphism.SalesEmployee;

public class UsePolymorphism {

 public static void main(String[] args) {
  Employee employee1 = new Employee("Rick", "Hightower", 32, true);
  SalesEmployee employee2 = new SalesEmployee("Whitney", "Hightower", 17,
    true, 0.05);
  HourlyEmployee employee3 = new HourlyEmployee("Bob", "Hightower", 27,
    true, 25.0);

  Employee[] employees = new Employee[] { employee1, employee2, employee3 };

  for (Employee employee : employees) {
   System.out.printf("%s %2.2f \n", employee.name(),
     employee.calculatePay());
  }

 }
}

Now let's look at the Java classes and Go structs and interface.

Payable interface and Employee struct GO

package polymorphism

type Payable interface {
 Name() string
 CalculatePay() float64
}

type Employee struct {
 firstName string
 lastName  string
 age       int
 current   bool
}

func (this *Employee) CalculatePay() float64 {
 return 0.0
}

func (this *Employee) Name() string {
 return this.firstName + " " + this.lastName
}


func NewEmployee(firstName string, lastName string, age int, current bool) *Employee {
 return &Employee{firstName, lastName, age, current}
}
... //getter and setter left out

Notice that you do not have to explicitly implement the interface like you do in Java. If you implement the methods, then you implement the interface.

Java Employee class with calculatePay and name method added

package com.example.polymorphism;

public class Employee {
 protected String firstName;
 protected String lastName;
 protected int age;
 protected boolean current;
 
 public Employee(String firstName, String lastName, int age, boolean current) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.age = age;
  this.current = current;
 }
 
 public double calculatePay()  {
  return 0.0d;
 }
 
 public String name() {
  return this.firstName + " " + this.lastName;
 }

//... getter and setter methods left out
}

HourlyEmployee GO

package polymorphism

type HourlyEmployee struct {
 Employee
 hourlyRate float64
}

func (this *HourlyEmployee) CalculatePay() float64 {
 return this.hourlyRate * 1000.0 //lookup hours worked in DB, but for this just hard code
}


func NewHourlyEmployee(firstName string, lastName string, age int, current bool, hourlyRate float64) *HourlyEmployee {
 return &HourlyEmployee{Employee{firstName, lastName, age, current}, hourlyRate}
}

HourlyEmployee java

package com.example.polymorphism;

public class HourlyEmployee extends Employee {

 private double hourlyRate;

 public HourlyEmployee(String firstName, String lastName, int age,
   boolean current, double commisionRate) {
  super(firstName, lastName, age, current);
  this.hourlyRate = commisionRate;
 }
 
 public double calculatePay()  {
  return this.hourlyRate * 1000.0; //lookup hours worked in DB, but for this just hard code
 }

...

}

SalesEmployee GO

package polymorphism

type SalesEmployee struct {
 Employee
 commisionRate float64
}

func (this *SalesEmployee) CalculatePay() float64 {
 return this.commisionRate * 100000000000
}

func NewSalesEmployee(firstName string, lastName string, age int, current bool, commisionRate float64) *SalesEmployee {
 return &SalesEmployee{Employee{firstName, lastName, age, current}, commisionRate}

}

SalesEmployee java

package com.example.polymorphism;

public class SalesEmployee extends Employee {

 private double commisionRate;

 public SalesEmployee(String firstName, String lastName, int age,
   boolean current, double commisionRate) {
  super(firstName, lastName, age, current);
  this.commisionRate = commisionRate;
 }
 
 public double calculatePay()  {
  return this.commisionRate * 100000000000l; 
 }

...
}

The output is the same.


func NewHourlyEmployee(firstName string, lastName string, age int, current bool, hourlyRate float64) *HourlyEmployee {
 return &HourlyEmployee{Employee{firstName, lastName, age, current}, hourlyRate}
}

Kafka and Cassandra support, training for AWS EC2 Cassandra 3.0 Training