# Object Oriented Programming

CIS 193

### Notes From Homework 0

Remember to run `gofmt`!

- `go` `vet`
- golint

### Structs

Aggregate data type that groups zero or more named values of arbitrary types

```type Person struct {
ID     int
Name   string
Age    int
}

var jim Person
jim.Age = 34```

Field order matters
Fields are only exported if uppercase first letter

### Struct Literals

```type Point struct {
X, Y int
}```

Values in order - every field must be included

`p1 := Point{1, 2}`

Field names and values

`p2 := Point{X: 2} // Y = 0`

Cannot use both forms in the same literal

If each field is comparable, structs can be compared using the == operator

### Struct Embedding

```type Circle struct {
}```

We can do

```type Point struct {
X, Y int
}

type Circle struct {
Center Point
}```

Why would we want to do this?

### Struct Embedding

Accessing fields

```var c Circle
c.Center.X = 3
c.Center.Y = 4

This is messy - what would be a better way?

### Struct Embedding and Anonymous Fields

```type Point struct {
X, Y int
}

type Circle struct {
Point
}```

Accessing fields

```var c Circle
c.X = 3
c.Y = 4

Point is embedded in Circle

### Struct Embedding and Anonymous Fields

How do we initialize structs with anonymous embedded fields?

`c := Circle{X: 4, Y: 5, Radius: 8} // compile error`

We have two options

```c := Circle{Point{8, 8}, 5}
c := Circle{
Point:  Point{X: 8, Y: 8},
Radius: 5, // this comma is necessary
}```

### Recursive Structs

Struct type T can't have field T

How can we make recursive types?

### Pointers

A variable is a piece of storage that contains a value

Pointers are the address of a variable, the location where a value is stored

### Pointer Syntax

Pointers allow us to read/update the value of a variable indirectly

```var x int
&x // the "address of x", has type *int```

`&x` is a pointer to an int

```func incr(p *int) int {
*p++  // doesn't change p
return *p
}

x := 1
incr(&x)              // x is now 2
fmt.Println(incr(&x)) // "3" (and x is 3)```

`*p` is the variable to which `p` points to

### Pointers with Structs

```type Person struct {
ID     int
Name   string
Age    int
}

var p Person
name := &p.Name
*name = "Bob"

var ptr *Person = &p
ptr.Name += " LastName"```

### Recursive Structs

```type Tree struct {
value       int
left, right *Tree
}```

### Methods

Declared as a variant of the ordinary function declaration, the extra type appears before the function name

```type Point struct {
X, Y float64
}

func (p Point) Distance(q Point) float64 {
return math.Hypot(q.X-p.X, q.Y-p.Y)
}

p := Point{1,1}
q := Point{2,2}
fmt.Println(p.Distance(q)) // 1.4142135623730951```

`p` is the method's receiver

Go typically uses short receiver names, eg: first letter of the type name

### Methods with a Pointer Receiver

Why is it useful to use pointers as receivers?

```func (p *Point) Scale(factor float64) {
p.X *= factor
p.Y *= factor
}```

Style: If one method for a type has a pointer receiver, then all should

Receivers can only be named types and pointers to named types

```(Point) // ok
(*Point) // ok

type P *int
(P) // not ok```

```p1 := &Point{1, 1}
p1.Scale(4)
fmt.Println(*p1) // {4, 4}```

What happens here?

```p1 := Point{1, 1}
p1.Scale(4)
fmt.Println(p)```

Go does an implicit *p or &p conversion on variables

### String()

Go has a String() method to help with printing

```func (c Celsius) String() string {
return fmt.Sprintf("%g°C", c)
}```

Works with:

```fmt.Println(c)
fmt.Println(c.String())
fmt.Printf("%v", c)
fmt.Printf("%s", c)```

### Composition by Struct Embedding

```type Point struct {
X, Y float64
}

type Circle struct {
Point
}```

Any Circle can access the methods of Point

```var c Circle
c.X = 2
c.Y = 4
c.Scale(4)
fmt.Printf("%+v\n", c) // {Point:{X:8 Y:16} Radius:0}```

The methods of Point are promoted to Circle

How do we handle encapsulation?

### Method Values and Expressions

Method value: binds a method to a receiver value

```distanceFromP := p.Distance
fmt.Println(distanceFromP(q))```

Method Expression

```distance := Point.Distance
fmt.Println(distance(p, q))```

### Basic Testing

Use `go test`

Applies to files that end in "_test.go"

Test function syntax

```import "testing"

func TestName(t *testing.T) {
//
}```

Must begin with "Test", the name of the rest of the function must begin with a capital letter

### Testing examples

```func TestPalindromeSimple(t *testing.T) {
if !IsPalindrome("racecar") {
t.Error(`IsPalindrome("racecar") = false`)
}
}

func TestIsPalindrome(t *testing.T) {
var tests = []struct {
input string
want  bool
}{
{"", true},
{"a", true},
{"aa", true},
{"ab", false},
}
for _, test := range tests {
if got := IsPalindrome(test.input); got != test.want {
t.Errorf("IsPalindrome(%q) = %v", test.input, got)
}
}
}```

### Homework 2

• Object Oriented Programming
• Due on Canvas on Tuesday, February 7th at 11:59 PM