Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Go
Code

Vamos Lá: Programaçã Orientada a Objetos em Golang

by
Difficulty:IntermediateLength:MediumLanguages:

Portuguese (Português) translation by Erick Patrick (you can also view the original English article)

Go é uma mistura de ideias novas e velhas. Ela tem uma abordagem inovativa e não tem medo de mudar as noções de "como fazer as coisas". Muitas pessoas nem sabem se Go é uma linguagem orientada a objetos. Deixe eu esclarecer: Ela é!

Nesse tutorial, aprenderemos tudo sobre projeto orientado a objetos em Go; como os pilares da programação orientada a objetos, como encapsulamento, herança e polimorfismo são expressos em Go; e como Go se compara a outras línguas.

A Filosofia de Projeto em Go

As raízes de Go são o C e, por alto, a família Algol. Ken Thompson, de certa forma, disse que Rob Pike, Robert Granger e ele próprio, uniram-se e perceberam que odiavam C++. Se é verdade ou não, o que sabemos é que Go é bem diferente de C++. Veremos mais disso depois. Go é simplicidade. Rob Pike explica melhor em Menos é exponecialmente mais.

Go versus Outras Linguagens

Go não tem classes, objetos, exceções nem modelos. Ela tem, porém, coletor de lixo e concorrência embutidos. A omissão mais aparente, em relação a orientação a objetos, é que não há hierarquia de tipos em Go. Isso vai de encontro à maioria das linguagens orientadas a objetos, como C++, Java, C#, Scala e até linguagens dinâmicas, como Python e Ruby.

Características de Orientação a Objetos em Go

Go não possui classes, mas tem tipos. No caso, tem estruturas. Estruturas são tipos definidos pelo usuário. Estruturas (com métodos) são parecidas com classes em outras linguagens.

Estruturas

A estrutura define estado. Eis uma estrutura Creature. Ela tem um campo Name e um semáforo chamado Real, que informa se é uma criatura real ou imaginária. Estrutura guarda apenas estado e não tem comportamento.

Métodos

Métodos são funções que operam em tipos específicos. Eles tem uma cláusula receptador que indica em que tipo de objetos eles operam. Eis um método Dump() que opera em estruturas Creature e imprime seu estado:

É uma sintaxe diferente, mas é bem explícita e clara (diferente do "this" ou mesmo do "self" em Python).

Implantação

Você pode implantar tipos anônimos dentro de outros tipos. Se implantar uma estrutura sem nome, essa estrutura provê seu estado (e métodos) para a estrutura implatada, diretamente. Por exemplo, FlyingCreature tem uma estrutura Creature não nomeada nela, e isso significa que FlyingCreature é uma Creature.

Agora, quando tiver uma instância de FlyingCreature, pode acessar os atributos Name e Real, diretamente.

Interfaces

Interfaces são a marca da orientação a objetos de Go. São tipos que declaram conjuntos de métodos. Assim como as interfaces em outras linguages, elas não possuem implementação.

Objetos que implementam todos os métodos de uma interface, automaticamente "herdam" essa interface. Não há herança, subclasse ou a palavra-chave "implements". No código abaixo, o tipo Foo implementa a interface Fooer (por padrão, interfaces em Go terminam em "er").

Padrão Orientado a Objetos: O Jeito Go

Vejamos como Go aplica os pilares da programação orientada a objetos: encapsulamento, herança e polimorfismo. Essas são características de linguagens baseadas em classe, as quais estão nas linguagens orientadas a objeto mais populares.

Em seu cerne, objetos são construtos de linguagem que possuem estado, comportamento que opera sobre o estado e os expõe, seletivamente, a outras partes do programa.

Encapsulamento

Go encapsula coisas a nível de pacote. Nomes que começam com letra minúscula são visíveis, apenas, dentro do pacote. Você pode esconder tudo em um pacote privado e expor, apenas, tipos, interfaces e funções fábricas específicas.

Para esconder o tipo Foo e expor apenas a interface, renomearíamo-na para letra mínuscula, foo, e proveríamos uma função NewFoo() retornando a interface pública Fooer:

Assim, códigos de outros pacotes poderiam usar NewFoo() e obter acesso à interface Fooer implementada pelo tipo interno foo:

Herança

Herança ou subclasse sempre foi um ponto controverso. Há inúmeros problemas com a herança por implementação (ao contrário da herança por interface). Herança múltipla, como em C++, Python e outras línguas, sofrem do problema do diamente da morte, mas mesmo a herança simples não é um piquenique, com o problema da frágil classe base.

Linguagens e pensamento orientado a objeto modernos favorecem a composição sobre a herança. Por isso, Go não possui qualquer tipo de hierarquia ou coisa do tipo. Podemos compartilhar detalhes de implementação através da composição. Mas Go, estranhamente (provavelmente, originou-se devido a pragmatismo), permite composição anônima via implantação.

Para todos os propósitos, compor por implantação de um tipo anônimo é o mesmo que herança por implementação. Uma estrutura implantada é tão frágil quanto uma classe base. Também podemos implantar uma interface, equivalendo a herança de interface em Java ou C++. Ela até gera erro em tempo de execução, erro não descoberto durante a compilação, se o tipo implantado não implementa toda a interface.

Aqui, SuperFoo implanta a interface Fooer, mas não implementa seus métodos. O compilador Go permitirá que crie SuperFoo e chame algum método de Fooer, mas, obviamente, falhará durante a execução. Isso compila:

Executar esse programa acaba em um panic:

Polimorfismo

Polimorfismo é a essência da programação orientada a objetos: a habilidade de tratar objetos de tipos diferentes, uniformimente, desde que adiram à mesma interface. Interfaces de Go provêem essa capacidade de forma bem direta e intuitiva.

Eis um exemplo elaborado onde várias criaturas (e uma porta!) implementando a interface Dumper, são criadas e salvas no tipo slice e seus métodos Dump() são chamados em cada uma delas. Perceba os diferentes tipos de instanciamento de objetos.

Conclusão

Go é uma genuína linguagem orientada a objetos. Ela permite modelagem baseada em objetos e promove boas práticas, como uso de interfaces, ao invés de hierarquias de tipos concretos. Go fez escolhas sintáticas incomuns, mas, no geral, trabalhar com tipos, métodos e interfaces é bem simples, leve e natural.

A técnica de implantação não é bem pura, mas, por pragmatismo, ela foi adicionada para não termos apenas a composição por nome.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.