🐹 Go

POO: Herança em Go (Golang): Um Guia Detalhado

```html

What is it and why? (a real-life analogy)

Imagine you work in a toy design bureau. Your company has decided to release a new line of robots. The first model is a Basic Robot. It has a head, a body, two arms, and two legs. It can walk, say "Hello!", and wave its hand.

A month later, you receive an order for a Chef Robot. It also needs to have a head, body, arms, and legs, and be able to walk and talk. But in addition, it needs to be able to cook scrambled eggs and wash dishes.

What will you do? Start drawing a new robot from scratch? That would be slow and foolish. Instead, you take the blueprints of the Basic Robot and simply add new parts and instructions to them. You say: "The new robot is the same as the basic one, but with additional capabilities."

This is exactly what inheritance is in programming. It is a mechanism that allows you to create a new class (or type) based on an existing one, borrowing all its properties and methods, and then adding something of your own or modifying what exists.

In simple terms: Inheritance is when a child inherits certain traits from parents (eye color, height), but also develops their own unique characteristics. In programming, the "parent" is the base type, and the "child" is the derived type.

Why is this needed?

  • Saves time: No need to write the same code for similar objects.
  • Logical structure: The code becomes clearer because it reflects real relationships ("A Chef Robot is a Robot").
  • Ease of modification: If you fix a bug in the base robot, all its "children" (Chef Robot, Cleaner Robot) automatically receive the fix.

Theory: how it works internally

In classical object-oriented programming (OOP), there are three pillars: encapsulation (data hiding), polymorphism (many forms), and inheritance. Inheritance is a mechanism that allows building a hierarchy of classes.

Imagine a tree. At the root is the most general class (e.g., "Transport"). From it branch more specific ones: "Land Transport", "Water Transport". From "Land Transport" come "Car", "Bicycle". Each subsequent level inherits everything from the previous one and adds its own specifics.

Key concepts:

  • Base type (parent, superclass): The type from which others inherit. Contains common fields and methods.
  • Derived type (child, subtype): The type that inherits. It can use everything the parent has, as well as add its own.
  • Method overriding: The child can change the behavior of a parent method. For example, the basic robot says "Hello", while the chef robot says "What shall we cook?"

What does this look like in computer memory?

When you create an object of a derived type, the computer allocates memory for all the parent's fields plus the child's fields. The parent's methods are physically located in one place, and the child simply "references" them if it hasn't overridden them.

Important: In Go (Golang), there is no classical class inheritance like in Java or C++. Instead, composition (type embedding) is used. But essentially, it's the same thing: one type is embedded into another, and all its methods become available. Go developers say: "Prefer composition over inheritance," but in practice, embedding works like inheritance.

Syntax in Go (Golang): all forms and variants

Go does not have the keywords extends or inherits. Everything is done through struct embedding. You simply specify the name of a struct inside another struct without a field name.

Basic form of embedding

// Base type
type Robot struct {
    Name string
}

// Method of the base type
func (r Robot) Greet() {
    fmt.Println("Hello! I am", r.Name)
}

// Derived type: embed Robot
type ChefRobot struct {
    Robot          // Embedding (anonymous field)
    Specialty string // Own field
}

func main() {
    // Create a chef
    chef := ChefRobot{
        Robot:     Robot{Name: "Cheffy"},
        Specialty: "Italian cuisine",
    }
    
    // Call the parent's method
    chef.Greet() // "Hello! I am Cheffy"
    
    // Access the parent's field
    fmt.Println(chef.Name) // "Cheffy"
}

Method overriding

If the child wants to change the behavior, it simply declares a method with the same name.

func (c ChefRobot) Greet() {
    fmt.Println("Greetings! I am head chef", c.Name, "specializing in", c.Specialty)
}

// Now chef.Greet() will call the new method, not the parent's

Calling the parent method

If you have overridden a method but want to call the parent's version inside it, you need to explicitly refer to the embedded type:

func (c ChefRobot) Greet() {
    c.Robot.Greet() // Call the parent method
    fmt.Println("I specialize in", c.Specialty)
}

Embedding multiple types

Go allows embedding multiple structs into one. This is similar to multiple inheritance, but without its problems (diamond inheritance).

type Walker struct{}
func (w Walker) Walk() { fmt.Println("Walking") }

type Talker struct{}
func (t Talker) Talk() { fmt.Println("Talking") }

type SuperRobot struct {
    Walker
    Talker
}

// SuperRobot can both walk and talk

Embedding interfaces

Not only structs but also interfaces can be embedded. This is used to create composite interfaces.

```