Rick

Rick
Rick

Friday, January 18, 2013

Java Developer Guide to Go Programming Collections Article 5

Go programming is strongly typed like Java, C and C++, but has built-in collection support like Python, and Ruby. Lists (growable arrays) in Go programming are called slices. Dictionary aka associative arrays (aka JavaScript objects like things) are called maps (just like the name java.util.Map).
To demonstrate collection usage and a few other language constructs, I added a Department that has a list of employees. I also threw in a few maps for good measure. What follows is Java with the functional equivalents in Go Programming....
First I show in Java and then you use your knowledge of Java and some labels/comments I added to see the equivalent in GO

Java Department class

package com.example.collections;

import java.util.ArrayList;
import java.util.List;

public class Department {
 
 private List employees = new ArrayList<>();
 private String name;
  
 public Department(String name, Employee... employees) {
  this.name = name;  
  for (Employee employee : employees) {
   this.employees.add(employee);
  }
 }


 public List getEmployees() {
  return employees;
 }
 public void setEmployees(List employees) {
  this.employees = employees;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 
 

}

Go Department class

package collections

type Department struct {
 name      string
 employees [] Employee
}

func NewDepartment(name string, employees ...Employee) *Department {
 return &Department{name, employees}
}

func (this *Department) Name() string {
 return this.name
}

func (this *Department) SetName(name string) {
 this.name = name
}

func (this *Department) Employees() []Employee {
 return this.employees
}

func (this *Department) SetEmployees(employees []Employee) {
 this.employees = employees
}

Now a new Company class to do some operations and construction of departments.
Now a new Company class to do some operations and construction of departments.

Java Company class

package com.example.collections;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Company {
 
 // (A) Create a map to hold employee id to hours worked this quarter
 private static Map empIdToHoursWorked = new HashMap<>();
 // (B) Create a map to hold employee id to sales this quarter
 private static Map empIdToSales = new HashMap<>();
 // (B.1) list of departments
 private static List departments = new ArrayList<>();
 // (B.2) map of department names to departments
 private static Map deptNameToDepartment = new HashMap<>();

 
 static {
  //(C) declare four departments
  Department sales =new Department("sales", new SalesEmployee(3L, "Whitney", "Hightower", 17,true, 0.05),
    new SalesEmployee(60L, "Alexander", "Hightower", 17,true, 0.05));
  


  Department engineering =new Department("engineering", 
        new Employee(1L, "Rick", "Hightower", 32, true), 
        new HourlyEmployee(2L, "Bob", "Hightower", 27, true, 25.0));



  Department hr =new Department("hr", 
    new Employee(10L, "Diana", "Hightower", 32, true), 
    new HourlyEmployee(20L, "Martha", "Hightower", 27, true, 25.0),
    new HourlyEmployee(30L, "Daniella", "Hightower", 27, true, 25.0));
  
  
  Department manufacturing =new Department("manufacturing", 
    new Employee(40L, "Joeseph", "Hightower", 32, true), 
    new HourlyEmployee(50L, "John", "Hightower", 27, true, 25.0));

  
  // (D) Bob worked 1750 hours this quarter. Martha and Daneilla each worked 350. How many did John work?
  empIdToHoursWorked.put(2L, 1750.0);
  empIdToHoursWorked.put(30L, 350.0);
  empIdToHoursWorked.put(20L, 350.0);
  empIdToHoursWorked.put(50L, 350.0);
  
  // (E) Whitney is our best sales person, but Alexander did good for a three year old.
  empIdToSales.put(60L, 5_000_000.0);
  empIdToSales.put(3L, 1_000_000.0);
  

  
  // (F) Add the three departments to the list of departments
  departments.add(engineering);
  departments.add(hr);
  departments.add(manufacturing);
  departments.add(sales);
  
  // (G) add some department to name mappings
  deptNameToDepartment.put(engineering.getName(), engineering);
  deptNameToDepartment.put(hr.getName(), hr);
  deptNameToDepartment.put(manufacturing.getName(), manufacturing);
  deptNameToDepartment.put(sales.getName(), sales);


 }
 
 // (H) Calculate Employee Cost
 public static double calculateCompanyEmployeeCost () {
  
  double totalCost = 0.0;
  //Nested for loop, looping over employees in each department.
  for (Department department : departments) {
   for (Employee employee : department.getEmployees()) {
    if (employee instanceof SalesEmployee) {
     ((SalesEmployee) employee).setQuarterlySales(empIdToSales.get(employee.getId()));
    } else if (employee instanceof HourlyEmployee) {
     ((HourlyEmployee) employee).setHoursWorkedThisQuarter(empIdToHoursWorked.get(employee.getId()));
    }
    totalCost += employee.calculatePay();
   }
  }
  
  return totalCost;
 }

}

Go Company Module

package collections

var (
 // (A) Create a map to hold employee id to hours worked this quarter
 empIdToHoursWorked map[int64]float64 = make(map[int64]float64)
 // (B) Create a map to hold employee id to sales this quarter
 empIdToSales map[int64]float64 = make(map[int64]float64)
 // (B.1) list of departments
 departments []*Department = make([]*Department, 0, 10)
 // (B.2) map of department names to departments
 deptNameToDepartment map[string]*Department = make(map[string]*Department)
)

func init() {
 //(C) declare four departments
 sales := NewDepartment("sales", NewSalesEmployee(3, "Whitney", "Hightower", 17, true, 0.05),
  NewSalesEmployee(60, "Alexander", "Hightower", 17, true, 0.05))

 engineering := NewDepartment("engineering",
  NewEmployee(1, "Rick", "Hightower", 32, true),
  NewHourlyEmployee(2, "Bob", "Hightower", 27, true, 25.0))

 hr := NewDepartment("hr",
  NewEmployee(10, "Diana", "Hightower", 32, true),
  NewHourlyEmployee(20, "Martha", "Hightower", 27, true, 25.0),
  NewHourlyEmployee(30, "Daniella", "Hightower", 27, true, 25.0))

 manufacturing := NewDepartment("manufacturing",
  NewEmployee(40, "Joeseph", "Hightower", 32, true),
  NewHourlyEmployee(50, "John", "Hightower", 27, true, 25.0))

 // (D) Bob worked 1750 hours this quarter. Martha and Daneilla each worked 350. How many did John work?
 empIdToHoursWorked[2] = 1750.0
 empIdToHoursWorked[30] = 350.0
 empIdToHoursWorked[20] = 350.0
 empIdToHoursWorked[50] = 350.0

 // (E) Whitney is our best sales person, but Alexander did good for a three year old.
 empIdToSales[60] = 5000000
 empIdToSales[3] = 1000000

 // (F) Add the three departments to the list of departments
 departments = append(departments, engineering, hr, manufacturing, sales)

 // (G) add some department to name mappings
 deptNameToDepartment[engineering.Name()] = engineering
 deptNameToDepartment[hr.Name()] = hr
 deptNameToDepartment[manufacturing.Name()] = manufacturing
 deptNameToDepartment[sales.Name()] = sales

}

// (H) Calculate Employee Cost
func CalculateCompanyEmployeeCost() float64 {

 totalCost := 0.0
 //Nested for loop, looping over employees in each department.
 for _, department := range departments {
  for _, employee := range department.Employees() {
   switch employee.(type) {
   case SalesEmployee:
    employee.(SalesEmployee).SetQuarterlySales(empIdToSales[employee.Id()])
   case HourlyEmployee:
    employee.(HourlyEmployee).SetHoursWorkedThisQuarter(empIdToHoursWorked[employee.Id()])
   }
   totalCost += employee.CalculatePay()
  }
 }
 return totalCost

}

Now the employees

Java Employees

package com.example.collections;

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


 public String getFirstName() {
  return firstName;
 }

 public String getLastName() {
  return lastName;
 }

 public int getAge() {
  return age;
 }

 public long getId() {
  return id;
 }

 public boolean isCurrent() {
  return current;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public void setAge(int age) {
  this.age = age;
 }

 public void setCurrent(boolean current) {
  this.current = current;
 }

}

package com.example.collections;

public class HourlyEmployee extends Employee {

 private double hourlyRate;
 private transient double hoursWorkedThisQuarter;



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


 public double getHourlyRate() {
  return hourlyRate;
 }

 public void setHourlyRate(double hourlyRate) {
  this.hourlyRate = hourlyRate;
 }

 public void setHoursWorkedThisQuarter(double hoursWorkedThisQuarter) {
  this.hoursWorkedThisQuarter = hoursWorkedThisQuarter;
 }


}

package com.example.collections;

public class SalesEmployee extends Employee {

 private double commisionRate;
 private transient double quarterlySales = -1;


 public SalesEmployee(Long id, String firstName, String lastName, int age,
   boolean current, double commisionRate) {
  super(id, firstName, lastName, age, current);
  this.commisionRate = commisionRate;
 }
 
 public double calculatePay()  {
  if (quarterlySales == -1) {
   throw new RuntimeException("quarterly sales not set");
  }
  return this.commisionRate * quarterlySales; 
 }


 public double getCommisionRate() {
  return commisionRate;
 }

 public void setCommisionRate(double commisionRate) {
  this.commisionRate = commisionRate;
 }
 
 public void setQuarterlySales(double sales) {
  this.quarterlySales = sales;
 }


}


Now the Go Employees
package collections

type Employee interface {
  CalculatePay() float64
  Name() string
  Id() int64
}

type EmployeeImpl struct {
 id   int64
 firstName string
 lastName  string
 age       int
 current   bool
}

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

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


func NewEmployee(id int64, firstName string, lastName string, age int, current bool) *EmployeeImpl {
 return &EmployeeImpl{id, firstName, lastName, age, current}
}

func (this *EmployeeImpl) FirstName() string {
 return this.firstName
}

func (this *EmployeeImpl) LastName() string {
 return this.lastName
}

func (this *EmployeeImpl) Age() int {
 return this.age
}

func (this *EmployeeImpl) Id() int64 {
 return this.id
}


func (this *EmployeeImpl) Current() bool {
 return this.current
}

func (this *EmployeeImpl) SetFirstName(name string) {
 this.firstName = name
}

func (this *EmployeeImpl) SetLastName(name string) {
 this.lastName = name
}

func (this *EmployeeImpl) SetAge(newAge int) {
 this.age = newAge
}

func (this *EmployeeImpl) SetCurrent(current bool) {
 this.current = current
}


func (this *SalesEmployeeImpl) SetHoursWorkedThisQuarter(sales float64) {
 this.quarterlySales = sales
}


package collections


type HourlyEmployee interface {
 Employee
 SetHoursWorkedThisQuarter(rate float64)
}

type HourlyEmployeeImpl struct {
 EmployeeImpl //HourlyEmployee extends Employee by using this anonymous field
 hourlyRate float64
 hoursThisQuarter float64
 
}

func NewHourlyEmployee(id int64, firstName string, lastName string, age int, current bool, 
      hourlyRate float64) *HourlyEmployeeImpl {
 return &HourlyEmployeeImpl{EmployeeImpl{id, firstName, lastName, age, current}, hourlyRate, 0.0}
}

func (this *HourlyEmployeeImpl) CalculatePay() float64 {
 return this.hourlyRate * this.hoursThisQuarter
}


func (this *HourlyEmployeeImpl) HourlyRate() float64 {
 return this.hourlyRate
}

func (this *HourlyEmployeeImpl) SetHourlyRate(rate float64) {
 this.hourlyRate = rate
}


func (this *HourlyEmployeeImpl) SetHoursWorkedThisQuarter(rate float64) {
 this.hoursThisQuarter = rate
}
package collections


type SalesEmployee interface {
 Employee
 SetQuarterlySales(rate float64)
}

type SalesEmployeeImpl struct {
 EmployeeImpl //Sales extends Employee by using this anonymous field
 commisionRate float64
 quarterlySales float64
 
}

func (this *SalesEmployeeImpl) CalculatePay() float64 {
 return this.commisionRate * this.quarterlySales
}

func NewSalesEmployee(id int64, firstName string, lastName string, age int, current bool, commisionRate float64) *SalesEmployeeImpl {
 return &SalesEmployeeImpl{EmployeeImpl{id, firstName, lastName, age, current}, commisionRate, 0.0}

}

func (this *SalesEmployeeImpl) CommisionRate() float64 {
 return this.commisionRate
}

func (this *SalesEmployeeImpl) SetCommisionRate(rate float64) {
 this.commisionRate = rate
}

func (this *SalesEmployeeImpl) SetQuarterlySales(sales float64) {
 this.quarterlySales = sales
}

Now the main method that call them both.

In Java...

package com.example;

import com.example.collections.Company;

public class UseCollection {
 
 public static void main(String[] args) {
  
  System.out.printf("Money spent on employees for last quarter %2.2f \n", Company.calculateCompanyEmployeeCost());

 }

}

In Go...

package main

import (
 "example/collections"
 "fmt"
)

func main() {

  fmt.Printf("Money spent on employees for last quarter %2.2f \n", collections.CalculateCompanyEmployeeCost());


}


Wednesday, January 16, 2013

Does Go Programming support polymorphism

When you search for Go polymorphism this page is the first thing that shows up. So everyone thinks Go is broken. This means that you should address the issue a little better. If you want to build a community. Since you didn't, I will.
package main
import "fmt";

type Fruit interface {
 Name() string;
 Eat() int;
}

type FruitImpl struct {
 calories int;
}
func (f *FruitImpl) Name() string { return "Fruit"; }
func (f *FruitImpl) Eat() int {
 fmt.Println("Inside Eat(), Name is", f.Name(), "calories=", f.calories);
 c := f.calories;
 f.calories = 0;
 return c;
}

type Apple struct { *FruitImpl; }
func (a *Apple) Name() string { return "Apple"; }

type Banana struct { *FruitImpl; }
func (b *Banana) Name() string { return "Banana"; }

func main() {
 a := &Apple { &FruitImpl{100} };
 b := &Banana { &FruitImpl{200} };
 fmt.Println("Apple Name is", a.Name());
 fmt.Println("Banana Name is", b.Name());
 fruits := [2]Fruit{a,b};
 for i := 0; i < 2; i++ {
  fruits[i].Eat();
 }
}

The above works as expected in Go 1.0. The output is:
Apple Name is Apple
Banana Name is Banana
Inside Eat(), Name is Fruit calories= 100
Inside Eat(), Name is Fruit calories= 200

You can see that Apple name is Apple so the method override worked. You can see that Banana name is Banana so the method override worked. But when you are inside of the method you are not dealing with the interface so you don't get what you expect. You are dealing with FruitImpl. Go does not support type inheritance. You can inherit behavior and data but not type. Thus FruitImpl is calling Name() on FruitImp as you would expect in Go. I think I have a fix for you, although, three years late. Read these articles which explain Go in Java terminology.... http://rick-hightower.blogspot.com/2013/01/java-guide-to-go-programming-article-1.html http://rick-hightower.blogspot.com/2013/01/java-guide-to-go-programming-article-2.html http://rick-hightower.blogspot.com/2013/01/java-guide-to-go-programming-article-3.html http://rick-hightower.blogspot.com/2013/01/java-guide-to-go-programming-article-4.html In short, Go does support polymorphism, data inheritance and behavior inheritance. Polymorphism is only achieved through Go interfaces not structs. You are sharing the Eat() from Fruit. You are sharing get polymorphic behavior for Name(). You are able to do a form of method overriding for Name() albeit through the Fruit interface not through the struct types.
package main

import "fmt"

type Fruit interface {
 Name() string
 Eat() int
}

type FruitImpl struct {
 calories int
 name     string //<--- added this
}

func (f *FruitImpl) Name() string { return f.name; }
func (f *FruitImpl) Eat() int {
 fmt.Println("Inside Eat(), Name is", f.name, "calories=", f.calories) //<--changed this
 c := f.calories
 f.calories = 0
 return c
}

type Apple struct{ *FruitImpl }
func (a *Apple) Name() string { return "Apple" }

type Banana struct{ *FruitImpl }
func (b *Banana) Name() string { return "Banana" }


func main() {
 a := &Apple{&FruitImpl{100, "apple"}}
 b := &Banana{&FruitImpl{200, "banna"}}
 fmt.Println("Apple Name is", a.Name())
 fmt.Println("Banana Name is", b.Name())
 fruits := [2]Fruit{a, b}
 for i := 0; i < 2; i++ {
  fruits[i].Eat()
 }
}

The output is:
Apple Name is Apple
Banana Name is Banana
Inside Eat(), Name is apple calories= 100
Inside Eat(), Name is banna calories= 200
You are sharing the Eat() from Fruit. You are sharing get polymorphic behavior for Name(). If you code to interfaces, then what you want to do is typically a bad design decision anyway. But if you must do something like this, then you can do a type like method override using functions as first class objects.
package main

import "fmt"

type Fruit interface {
 Name() string
 Eat() int
}

type FruitImpl struct {
 calories int
 name func (f *FruitImpl) string 
}

func (f *FruitImpl) Name() string { 
 return f.name(f); 
}

func (f *FruitImpl) Eat() int {
 nameFunc:=f.name
 fmt.Println("Inside Eat(), Name is", nameFunc(f), "calories=", f.calories) //<--changed this
 c := f.calories
 f.calories = 0
 return c
}

type Apple struct{ *FruitImpl }
type Banana struct{ *FruitImpl }

func main() {
 a := &Apple{&FruitImpl{100, func (a *FruitImpl) string { return "Apple" }}}
 b := &Banana{&FruitImpl{200, func (b *FruitImpl) string { return "Banana" }}}
 fmt.Println("Apple Name is", a.Name())
 fmt.Println("Banana Name is", b.Name())
 fruits := [2]Fruit{a, b}
 for i := 0; i < 2; i++ {
  fruits[i].Eat()
 }
}

The internal polymorphic behavior is sort of a crutch and more of an edge case of polymorphism, but as you can see, it can be supported by Go as shown above. The output now matches your desired result.
Apple Name is Apple
Banana Name is Banana
Inside Eat(), Name is Apple calories= 100
Inside Eat(), Name is Banana calories= 200

Tuesday, January 15, 2013

Java Guide to Go Programming article 4: Polymorphism II

In the last article (article 3), we covered polymorphism in Go. Go does not have type inheritance like C++, Java, Python, Ruby, C#, Dart, ... well you get the idea. It does have inheritance via structs but you inherit data and behavior (functions), not types.


Go inheritance is via structs and anonymous fields unlike well, umm, err everybody else (see last article to see an example of this). Polymorphism is mostly achievable via interfaces. In the Java sense, only Go interfaces specify types not classes, umm, err, structs. From an interface you can cast to another interface if the underlying object implements that interface.


The last set of Go examples showed something that really looked like Java method overriding. It looked like it. Smelled like it and even behaved like it, but none of it was possible without the Go interface.


You may have heard of this principle if you are long time Java or C# developer: program to interfaces. Well in Go, you don't have much choice. Interfaces not classes or structs are the true road to polymorphic behavior.


The functionality from Employee.Name() was inherited by SalesEmployee and HourlyEmployee. Also HourlyEmployee and SalesEmployee appeared to override the behavior of Employee.Calc with HourlyEmployee.Calc and SalesEmployee.Calc. However, you can't store a list of Employee instances in a Go array or a Go slice (a Go slice is like a java.util.List while a Go array is like well a Java array). An Employee instance is always an Employee instance in Go. A SalesEmployee is always a SalesEmployee. It is not like Java where a SalesEmployee is an Employee. To get the polymorphic behavior in our example, we had store the list of employees in a Payable interface array. The typing, if you will, is from the interface not the struct. The interface is the contract for behavior. A SalesEmployee, Employee and HourlyEmployee are all Payable instances so to speak.


Let's review briefly.

Revisit Polymorphism example in GO

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


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

/* Notice that Employee implements the Payable interface but we dont have to say it does. There is no Employee implements Payable like in Java and C#. */

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}
}

...

type HourlyEmployee struct {
 Employee //HourlyEmployee extends Employee by using this anonymous field
 hourlyRate float64
}

/* 
HourlyEmployee.CalculatePay....
This CalculatePay effectively overrides the one defined in Employee. 
HourlyEmployee inherits the data from Employee and the method Name().
*/
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}
}

...

type SalesEmployee struct {
 Employee //SalesEmployee extends Employee by using this anonymous field
 commisionRate float64
}

/* 
SalesEmployee.CalculatePay....
This SalesEmployee.CalculatePay effectively overrides the one defined in Employee. 
SalesEmployee inherits the data from Employee and the method Name() from Employee.
*/
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}

}

You will read that Go programming does not allow method overriding and while technically true, if you can define an interface like Payable, then you can treat a motley group of as a single type and you get what looks like method overriding and inheritance in Java.

Revisit Polymorphism example in GO

package main

import (
 "example/polymorphism"
 "fmt"
)

func main() {

 /* employee1 is a Employee, employee2 is a SalesEmployee, and employee3 is a HourEmployee, but
    employee2 is not an Employee, and employee3 is not an Employee. Type inheritance does not exist. */
 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)

 
 // You can't store them in an array of Employees like you could in Java.
 //employees := []*polymorphism.Employee{employee1, employee2, employee3}
 
 //You can store them in an array of Payable interfaces
 employees := []polymorphism.Payable{employee1, employee2, employee3}
 

 for _, employee := range employees {
  fmt.Printf("%s %2.2f \n", employee.Name(), employee.CalculatePay())
 }
 
 /*  You can't cast one employee type to another like this. */
 //emp := employee2.(polymorphism.Employee) //Error Go does not have type inheritance!
 var obj interface{} = employee1  //interface {} is sort of like Java's Object as Go is interface centric
 emp := obj.(polymorphism.Payable) //This is like a cast to Payable, emp is Payable not employee
 fmt.Println(emp)
 
 //var emp2 *polymorphism.Employee = employee2 //Error Go does not have type inheritance, 
             // you a SalesEmployee can never be a Employee
 var emp2 *polymorphism.SalesEmployee = employee2 //This is allowed because employee2 is a SalesEmployee
 fmt.Println(emp2)
 
 /* All polymorhism, method overiding, is done through interfaces not struct instances. */
}

In the Java realm, there are also interfaces. In Java both interfaces and classes can define the type of an instance. In Go, it is really just the interface that allows instances to be grouped together.

Revisit Java Polymorphism example this time with interfaces


package com.example.polymorphism2;

public interface Payable {
 String name();
 double calculatePay();
}

...
package com.example.polymorphism2;

public class Employee implements Payable {
 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;
 }

...
package com.example.polymorphism2;

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
 }


...
package com.example.polymorphism2;

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; 
 }
...
package com.example;

import com.example.polymorphism2.Employee;
import com.example.polymorphism2.HourlyEmployee;
import com.example.polymorphism2.SalesEmployee;
import com.example.polymorphism2.Payable;

public class UsePolymorphism2 {

 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());
  }

  /*  You can't cast one employee type to another like this in Go, but no problem for Java */
  Employee emp = employee2; //No Error for Java as it does have type inheritance
  Payable payable = employee2; //Works with interfaces too
  System.out.println(emp);
  System.out.println(payable);

  
  SalesEmployee saleEmployee = (SalesEmployee) emp; //You can downcast and up cast as type inheritance is its things
  System.out.println(saleEmployee);
 }
}

Can you achieve more parity with Java method overriding in Go. Not really. You can create something that is more similar (or less similar in concept) that allows you to switch out methods at runtime, but Go is Go and Java is Java. Embrace Go's emphasis on interfaces and its style and brand of polymorphism and you will learn to love it. It is the loose coupling and late bound interfaces that allow great management of dependencies and that speed up Go compilation. And if you feel design by interface was good in Java then you will love Go because it forces it.
Let's take another Go at doing method overriding in Go. This time I will start with the main method.

Revisit Go Polymorphism example this time with no interfaces


package main

import (
 "example/override"
 "example/polymorphism" 
 "fmt"
)

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

 employees := []*override.Employee{employee1, employee2, employee3}

 for _, employee := range employees {
  fmt.Printf("** %s %2.2f \n", employee.Name(), employee.CalculatePay())
 }
 
 /*  They are all employees so this is no longer a problem */
 emp := employee2 
 fmt.Println(emp)

 var obj interface{} = employee1  //interface {} is sort of like Java's Object as Go is interface centric
 emp1 := obj.(polymorphism.Payable) //This is like a cast to Payable, emp is Payable not employee
 fmt.Println(emp1)

}


I know what you are thinking. I just told you that you can't group HourlyEmployee, SalesEmployee and regular Employees into one array, but then I write an example were ya do it. Tricky Ricky. I assure you when this program executes the same behavior as before and it changes polymorphically too. Before you look at the answer, ponder how I did this given the above statements of types not being inheritable.
Times up. I cheated. Go programming has first class functions. Functions are objects. They can be assigned. The instances employee1, employee2, and employee3 are all Employees now. There is no HourlyEmployee struct or SalesEmployee struct. When I construct the Employees, I populate the Employee struct with the right functions and this gives me the desired polymorphic behavior but all with one type, i.e., Employee. I utilize closures and lambda functions to capture hourlyRate and commisionRate.

Revisit Go Polymorphism example this time with no interfaces

package override

type empType int

const (
 hourly empType = iota
 sales empType = iota
 regular empType = iota 
)

type Employee struct {
 firstName        string
 lastName         string
 age              int
 current          bool
 calculatePayFunc func(this *Employee) float64
 nameFunc         func(this *Employee) string
 etype empType 
}

func (this *Employee) CalculatePay() float64 {
 calcFunc := this.calculatePayFunc
 return calcFunc(this)
}

func (this *Employee) Name() string {
 nameFunc := this.nameFunc
 return nameFunc(this)
}

func newEmployee(firstName string, lastName string, age int, current bool,
 calcFunc func(this *Employee) float64, nameFunc func(this *Employee) string, etype empType) *Employee {
 if nameFunc == nil {
  nameFunc = func(this *Employee) string { return lastName + " " + firstName }
 }
 if calcFunc == nil {
  calcFunc = func(this *Employee) float64 { return 1000 }
 }
 
 return &Employee{firstName, lastName, age, current, calcFunc, nameFunc, etype}
}

func NewEmployee(firstName string, lastName string, age int, current bool) *Employee {
 return newEmployee(firstName, lastName, age, current, nil, nil, regular)
}

func NewHourlyEmployee(firstName string, lastName string, age int, current bool, hourlyRate float64) *Employee {
 calcFunc:= func (this *Employee)  float64 {return hourlyRate * 1000}
 return newEmployee(firstName, lastName, age, current, calcFunc, nil, hourly)
}


func NewSalesEmployee(firstName string, lastName string, age int, current bool, commisionRate float64) *Employee {
 calcFunc:= func (this *Employee)  float64 {return commisionRate * 100000000000}
 return newEmployee(firstName, lastName, age, current, calcFunc, nil, sales)
}

...
Now let me show you how you could do the above with Java closures and lambda support, but first I need to invent a time machine because that doesn't come out until Java 8.
I don't know what is going to be in article 5 yet, but I am open to suggestions.

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}
}

Java Guide to Go Programming article 2: Inheritance

If you are just tuning in, I thought it would be instructive if I demonstrated new Go Programming Features by comparing them to Java code features. This way if you are new to Go Programming, you can pick up the concepts quickly without tons of explanation (this links to the first article)

In the first article, we had just the Employee class with getter/setter methods. We implemented it in idiomatic Java and then again in idiomatic Go. Now let's continue our employee example in Java and Go. First Java.

Java Employee

/java-examples/src/com/example/inheritance/Employee.java
package com.example.inheritance;

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 String getFirstName() {
  return firstName;
 }

 public String getLastName() {
  return lastName;
 }

 public int getAge() {
  return age;
 }

 public boolean isCurrent() {
  return current;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public void setAge(int age) {
  this.age = age;
 }

 public void setCurrent(boolean current) {
  this.current = current;
 }

 @Override
 public String toString() {
  return "Employee [firstName=" + firstName + ", lastName=" + lastName
    + ", age=" + age + ", current=" + current + "]";
 }

}

Go Employee

/examples/src/example/inheritance/employee.go
package inheritance

import "strconv"

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

func NewEmployee(firstName string, lastName string, age int, current bool) *Employee {
 return &Employee{firstName, lastName, age, current}
}

func (this *Employee) FirstName() string {
 return this.firstName
}

func (this *Employee) LastName() string {
 return this.lastName
}

func (this *Employee) Age() int {
 return this.age
}

func (this *Employee) Current() bool {
 return this.current
}

func (this *Employee) SetFirstName(name string) {
 this.firstName = name
}

func (this *Employee) SetLastName(name string) {
 this.lastName = name
}

func (this *Employee) SetAge(newAge int) {
 this.age = newAge
}

func (this *Employee) SetCurrent(current bool) {
 this.current = current
}

func (this *Employee) String() string {
 return "Employee [firstName=" + this.firstName + ", lastName=" + this.lastName +
  ", age=" + strconv.Itoa(this.age) + ", current=" + strconv.FormatBool(this.current) + "]"
}

Java HourlyEmployee

/java-examples/src/com/example/inheritance/HourlyEmployee.java
package com.example.inheritance;

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 getHourlyRate() {
  return hourlyRate;
 }

 public void setHourlyRate(double hourlyRate) {
  this.hourlyRate = hourlyRate;
 }

 @Override
 public String toString() {
  return "HourlyEmployee [firstName=" + firstName + ", lastName="
    + lastName + ", age=" + age + ", current=" + current
    + ", hourlyRate=" + hourlyRate + "]";
 }

}

Go HourlyEmployee

/examples/src/example/inheritance/hourly.go
package inheritance

import "strconv"

type HourlyEmployee struct {
 Employee
 hourlyRate float64
}

func NewHourlyEmployee(firstName string, lastName string, age int, current bool, hourlyRate float64) *HourlyEmployee {
 newEmp := new(HourlyEmployee)
 newEmp.hourlyRate = hourlyRate
 newEmp.firstName = firstName
 newEmp.lastName = lastName
 newEmp.age = age
 newEmp.current = current
 return newEmp
}

func (this *HourlyEmployee) HourlyRate() float64 {
 return this.hourlyRate
}

func (this *HourlyEmployee) SetHourlyRate(rate float64) {
 this.hourlyRate = rate
}

func (this *HourlyEmployee) String() string {
 return "HourlyEmployee [firstName=" + this.firstName + ", lastName=" + this.lastName +
  ", age=" + strconv.Itoa(this.age) + ", current=" + strconv.FormatBool(this.current) +
  ", hourlyRate=" + strconv.FormatFloat(float64(this.hourlyRate), 'f', 2, 32) + "]"
}

Java SalaryEmployee

/java-examples/src/com/example/inheritance/SalaryEmployee.java
package com.example.inheritance;

public class SalaryEmployee extends Employee {

 private double commisionRate;

 public SalaryEmployee(String firstName, String lastName, int age,
   boolean current, double commisionRate) {
  super(firstName, lastName, age, current);
  this.commisionRate = commisionRate;
 }

 public double getCommisionRate() {
  return commisionRate;
 }

 public void setCommisionRate(double commisionRate) {
  this.commisionRate = commisionRate;
 }

 @Override
 public String toString() {
  return "SalaryEmployee [firstName=" + firstName + ", lastName="
    + lastName + ", age=" + age + ", current=" + current
    + ", commisionRate=" + commisionRate + "]";
 }

}

Go SalaryEmployee

/examples/src/example/inheritance/salary.go
package inheritance

import "strconv"

type SalaryEmployee struct {
 Employee
 commisionRate float64
}

func NewSalaryEmployee(firstName string, lastName string, age int, current bool, commisionRate float64) *SalaryEmployee {
 newEmp := new(SalaryEmployee)
 newEmp.commisionRate = commisionRate
 newEmp.firstName = firstName
 newEmp.lastName = lastName
 newEmp.age = age
 newEmp.current = current
 return newEmp
}

func (this *SalaryEmployee) CommisionRate() float64 {
 return this.commisionRate
}

func (this *SalaryEmployee) SetCommisionRate(rate float64) {
 this.commisionRate = rate
}

func (this *SalaryEmployee) String() string {
 return "SalaryEmployee [firstName=" + this.firstName + ", lastName=" + this.lastName +
  ", age=" + strconv.Itoa(this.age) + ", current=" + strconv.FormatBool(this.current) +
  ", commisionRate=" + strconv.FormatFloat(float64(this.commisionRate), 'f', 2, 32) + "]"
}

Using Classes Java

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

import com.example.inheritance.Employee;
import com.example.inheritance.HourlyEmployee;
import com.example.inheritance.SalaryEmployee;

public class UseInheritance {

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

  System.out.println(employee1);
  System.out.println(employee2);
  System.out.println(employee3);

  employee1.setLastName("Smith");
  employee1.setAge(45);

  System.out.printf("Name = %s, %s | Age = %d \n",
    employee1.getFirstName(), employee1.getLastName(),
    employee1.getAge());
  System.out.printf("Name = %s, %s | Age = %d \n",
    employee2.getFirstName(), employee2.getLastName(),
    employee2.getAge());
  System.out.printf("Name = %s, %s | Age = %d \n",
    employee3.getFirstName(), employee3.getLastName(),
    employee3.getAge());

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

  for (Object employee : employees) {
   System.out.println(employee);
  }

 }
}

Using Classes Go

/examples/src/example/inheritance/useInheritance.go
package main

import (
 "example/inheritance"
 "fmt"
)

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

 fmt.Println(employee1)
 fmt.Println(employee2)
 fmt.Println(employee3)

 employee1.SetLastName("Smith")
 employee1.SetAge(45)

 fmt.Printf("Name = %s, %s | Age = %d \n", employee1.FirstName(), employee1.LastName(), employee1.Age())
 fmt.Printf("Name = %s, %s | Age = %d \n", employee2.FirstName(), employee2.LastName(), employee2.Age())
 fmt.Printf("Name = %s, %s | Age = %d \n", employee3.FirstName(), employee3.LastName(), employee3.Age())

 employees := []interface{}{employee1, employee2, employee3}

 for _, employee := range employees {
  fmt.Println(employee)
 }

}

The output is the same.

Employee [firstName=Rick, lastName=Hightower, age=32, current=true]
SalaryEmployee [firstName=Whitney, lastName=Hightower, age=17, current=true, commisionRate=0.05]
HourlyEmployee [firstName=Bob, lastName=Hightower, age=27, current=true, hourlyRate=25.00]
Name = Rick, Smith | Age = 45 
Name = Whitney, Hightower | Age = 17 
Name = Bob, Hightower | Age = 27 
Employee [firstName=Rick, lastName=Smith, age=45, current=true]
SalaryEmployee [firstName=Whitney, lastName=Hightower, age=17, current=true, commisionRate=0.05]
HourlyEmployee [firstName=Bob, lastName=Hightower, age=27, current=true, hourlyRate=25.00]

Java Guide to Go Programming article 1: Class and Encapsulation

I don't know if this is going to be a one time thing or something that I do on a regular basis. I thought it would be instructive to compare/contrast Go Programming to a mainstream language like Java. What follows is Java code listings followed by Go Programming listings. When possible I try to Idioms and code conventions adopted by those languages. To be fair on LOC, I use the built-in code formatting support of Eclipse.

I used the Goclipse Eclipse plugin and Java Eclipse IDE to format the code. I start with hello world and then I create a simple Employee class to show encapsulation and grouping behavior and data in the two languages.

Hello World! Java

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

public class Hello {

 public static void main(String[] args) {
  System.out.println("Hello World!");
 }
}

Now the same in Go Programming.
package main

import "fmt"

func main() {
 fmt.Println("Hello World!")
}

I had to get hello world out of the way. :)

Idiomatic Java class with getters and setters (properties) for Employee

/java-examples/src/com/example/encapsulation/Employee.java
package com.example.encapsulation;

public class Employee {
 private String firstName;
 private String lastName;
 private int age;
 private 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 String getFirstName() {
  return firstName;
 }

 public String getLastName() {
  return lastName;
 }

 public int getAge() {
  return age;
 }

 public boolean isCurrent() {
  return current;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public void setAge(int age) {
  this.age = age;
 }

 public void setCurrent(boolean current) {
  this.current = current;
 }

 @Override
 public String toString() {
  return "Employee [firstName=" + firstName + ", lastName=" + lastName
    + ", age=" + age + ", current=" + current + "]";
 }

}

Idiomatic Go Programming class equivalent with getters and setters (properties) for Employee

/examples/src/example/encapsulation/employee.go
package encapsulation

import "strconv"

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

func NewEmployee(firstName string, lastName string, age int, current bool) *Employee {
 return &Employee{firstName, lastName, age, current}
}

func (this *Employee) FirstName() string {
 return this.firstName
}

func (this *Employee) LastName() string {
 return this.lastName
}

func (this *Employee) Age() int {
 return this.age
}

func (this *Employee) Current() bool {
 return this.current
}

func (this *Employee) SetFirstName(name string) {
 this.firstName = name
}

func (this *Employee) SetLastName(name string) {
 this.lastName = name
}

func (this *Employee) SetAge(newAge int) {
 this.age = newAge
}

func (this *Employee) SetCurrent(current bool) {
 this.current = current
}

func (this *Employee) String() string {
 return "Employee [firstName=" + this.firstName + ", lastName=" + this.lastName +
  ", age=" + strconv.Itoa(this.age) + ", current=" + strconv.FormatBool(this.current) + "]"
}

Note that I used the variable this but it is more common to use things like emp or e. I used this to make it more clear to Java programmers what I was doing.

Using Java Employee class

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

import com.example.encapsulation.Employee;

public class UseEncapsulation {

 public static void main(String[] args) {
  Employee employee = new Employee("Rick", "Hightower", 32, true);
  System.out.println("" + employee);

  employee.setLastName("Smith");
  employee.setAge(45);

  System.out.printf("Name = %s, %s | Age = %d \n",
    employee.getFirstName(), employee.getLastName(),
    employee.getAge());
 }
}

Using Go Programming struct (aka class)

examples/src/useEncapsulation.go
package main

import (
 "example/encapsulation"
 "fmt"
)

func main() {
 employee := encapsulation.NewEmployee("Rick", "Hightower", 32, true)
 fmt.Println(employee)

 employee.SetLastName("Smith")
 employee.SetAge(45)

 fmt.Printf("Name = %s, %s | Age = %d \n", employee.FirstName(), employee.LastName(), employee.Age())

}

The output for both are the same
Employee [firstName=Rick, lastName=Hightower, age=32, current=true]
Name = Rick, Smith | Age = 45 
More to come....
Kafka and Cassandra support, training for AWS EC2 Cassandra 3.0 Training