Criando uma classe

Criando uma classe

Doggie Dady

Índice das lições


Em torno do tema da criação de uma classe vamos apresentar mais componentes do IDE do Smalltalk.

Vamos criar uma classe que represente uma conta num banco. Faremos isto de forma simplista para não incorrer em detalhes muito complexos e irrelevantes para o nosso objetivo de mostrar o básico da linguagem e do ambiente de programação.

Nossa classe definirá que seus objetos são capazes de "memorizar" o saldo de cada conta. E que podemos fazer depósitos e retiradas em cada conta. O saldo evoluirá em função desses depósitos e retiradas.

O tratamento de erros será negligenciado para tornar o código mais simples e legível ao mesmo tempo evitando sobrecarregar a lição com muita informação que poderá ser absorvida depois em outras lições que tratem de temas mais específicos.

Continuaremos, por enquanto, privilegiando o uso do Playground como ferramenta didática e de fácil uso.

System Browser

System Browser é um browser que permite que você navegue pelas classes e códigos que você criou ou introduza novas classes e códigos associados a elas.

Componentes do System Browser

Acima temos a janela do System Browser aberta com a classe Collection selecionada.

Vemos as 6 seções ou painéis que compõem o System Browser.

Da esquerda para a direita e de cima para baixo:

  • Packages
  • Classes
  • Protocols
  • Methods
  • Code
  • Critics

Vamos descrever sucintamente cada um.

Packages

Neste painel são mostrados os pacotes que existem no ambiente. No nosso exemplo está selecionado o pacote Collections-Abstract. Um pacote contém várias classes.

Classes

Neste painel são mostradas as classes do pacote selecionado. No nosso exemplo selecionamos a classe Collection.

Protocols

Neste painel basicamente são mostrados os protocolos que categorizam os métodos da classe selecionada.

Methods

Neste painel aparecem os métodos implementados na classe selecionada.

Code

Neste painel aparece código de acordo com o que está selecionado no conjunto dos 4 painéis acima. No nosso exemplo aparece o código que define a classe Collection.

Critics

Neste painel aparecem mensagens de crítica informando sobre alguns problemas potenciais relativos à codificação.

Criando uma classe no System Browser

Antes de criar a classe devemos criar o pacote onde ela vai residir.

Criando o package e adicionando uma tag

Vamos criar o package-tag MyBank-Core.

Clique com o botão direito em qualquer ponto do painel Packages para obter o menu de contexto e selecione o submenu New package.

Entre o nome do pacote.

Use novamente o menu de contexto para definir uma tag.

Logo abaixo do painel que mostra os pacotes (packages) há dois radio buttonsAll Packages e Scoped View. Selecione Scoped View.

Criando a classe

Expanda o pacote Bank para que a tag Core apareça.

No painel Code você vê um template para criação de uma classe no package-tag Bank-Core. O template é uma expressão do Smalltalk que cria uma classe. É uma expressão como outra qualquer do Smalltalk. Repetimos a expressão abaixo:

Object subclass: #NameOfSubclass
    instanceVariableNames: ''
    classVariableNames: ''
    package: 'MyBank-Core'

Vamos modificar a expressão para que ela crie a classe Account.

Cuidado para não remover o #. O argumento dessa expressão que representa o nome da classe deve ser um símbolo (Symbol) (Veja a lição Conhecendo alguns objetos básicos).

Agora vamos criar a nossa classe, o que fazemos através do submenu Accept do menu de contexto (que aparece ao clicar com o botão direito do mouse).

E a classe é criada.

A expressão abaixo, que cria a classe Account, poderia ser avaliada, por exemplo, no Playground usando Do it. E a classe seria criada da mesma forma.
Object subclass: #Account
    instanceVariableNames: ''
    classVariableNames: ''
    package: 'MyBank-Core'

Definindo variáveis de instância

Vamos definir a variável de instância balance. Para isso edite a expressão que cria a classe conforme mostrado abaixo e use o submenu Accept como fez antes. As variáveis de instância são criadas através do argumento de instanceVariableNames:.

Abaixo do painel que apelidamos de Protocols selecione o radio button Vars. As variáveis de instância da classe vão aparecer em vez da lista de protocolos (protocols). Constate que balance aparece.

Variável de instância é parte da estrutura que já mencionamos que uma classe define e que todas as suas instâncias vão ter como recurso de armazenagem do seu estado. No nosso caso significa que a classe ao criar uma instância, com a expressão Account new, por exemplo, vai prover o objeto criado de um local para armazenar o valor da variável, no caso o saldo da conta (balance).
As variáveis de instância são privadas. Quem usa um objeto não tem acesso a uma variável de instância diretamente mas somente através dos métodos.

Definindo métodos de instância

Abaixo dos 4 painéis temos as abas CommentAccount e + Inst. side method. Selecione a aba + Inst. side method. Verá então o template para a forma como um método deve ser escrito.

template tem partes obrigatórias e outras opcionais. Na primeira linha colocamos a assinatura do método que descreve o seletor da mensagem e os parâmetros que deverão ser passados como argumentos na mensagem. É a única parte obrigatória.
As linhas seguintes com textos entre " são comentários e não tem nenhum efeito na execução e são usados com fins de documentação.
Mais abaixo temos uma declaração de variáveis locais entre |.
E finalmente o código que define como a mensagem com o seletor que coincide com a assinatura do método vai ser respondida com um efeito colateral (opcional) e o valor de retorno.

Vamos criar três métodos para a classe Accountbalancedeposit: e withdraw:.

O nosso método balance é executado quando uma instância da classe Account recebe a mensagem unária balance.

Valor de retorno de um método

O valor de retorno é especificado após o ˆ. Caso seja omitido fica implicito que o valor de retorno é o próprio objeto (self*).

self é uma pseudo-variável e palavra reservada que referencia o objeto que é o receptor da mensagem que acionou o método.

Criando o método balance

Os métodos são públicos. Isto é, fazem parte da interface pública dos objetos e podem ser acionados por mensagens enviadas ao objeto.
Se é o primeiro método que está criando na imagem o diálogo abaixo vai ser apresentado. Entre a sua identificação que será associada daqui em diante aos códigos que criar.

O método balance deve aparecer na lista do painel que apelidamos de Methods.

O método balance é um método do tipo accessor. Especificamente é um getter. Um método para dar acesso de leitura a uma variável de instância específica. No caso a variável de instância balance. A convenção e dar ao método o mesmo nome da variável a que dá acesso.

Criando o método deposit:

Faça de forma similar ao que fez quando criou o método balance.

O método deposit: responde a uma mensagem do tipo com palavras-chaves (keyword message) e possui um argumento.

O método deposit: não possui uma linha contendo ˆ. Logo o retorno implícito é self. O método é equivalente ao mostrado abaixo.

Criando o método withdraw:

O método initialize

Quando criamos uma instância de uma classe as variáveis de instância tem o valor nil* por default.

nil é um valor que quando atribuido a uma variável significa que ela não referencia nenhum objeto. Quando uma variável que não contém nenhuma referência "recebe uma mensagem" acontece um erro.

Quando uma classe recebe a mensagem new ela cria uma instância e invoca o método initialize. Mas você tem que criar este método na sua classe se quiser fazer algumas inicializações. No caso da variável balance vamos estabelecer que toda conta recém criada tenha balance igual a zero. Criamos então o método initialize como abaixo mostrado.

Colocar a expressão super initialize no método de instância initialize é uma convenção que previne a necessidade de executar código herdado. No nosso caso é supérfluo. Voltaremos a isso quando discutirmos herança.

Definindo métodos de classe

Vamos definir um método de classe que crie uma instância de Account com um saldo inicial armazenado em balance.

Clique no radio button Class side para poder criar o método de classe no class side.

Selecione a aba + Class side method. Vai ver um template igual ao que viu quando foi criar o método no instance side.

Vamos criar o método newWithInitialBalance:.


Vamos analisar o código. Nele há o trecho

^ self new
    initialBalance: anAmount

ˆ no início indica que o resultado da expressão

self new
    initialBalance: anAmount

será retornado pelo método.

Há duas mensagens na expressão: new e initialBalance:.

A primeira mensagem, new, tem como receptor self.

Mas que objeto é referenciado por esse self?

Se estivéssemos no instance side self estaria referenciando o objeto que estivesse respondendo à mensagem.

Como estamos no class side o objeto que está respondendo à mensagem é a classe. E já vimos que as classes sabem responder à mensagem new. Elas respondem a essa mensagem criando uma instância de si mesma e excutando o método initialize. Logo o resultado de self new é uma instância da classe Account.

A segunda mensagem initialBalance: é enviada a este objeto criado com self new. Como esta mensagem é enviada a uma instância ela deve ser respondida por um método de instância. Como ainda não criamos o método initialBalance: vamos fazê-lo no instance side.

Variável de classe

No momento não temos necessidade de criar uma variável de classe. Mas caso precisássemos de uma ela seria criada de forma semelhante à criação da variável de instância só que como o argumento de classVariableNames:. As variáveis de classe valem para toda a classe e podem ser referenciadas nos código tanto no instance side como no class side. Mas não se preocupe agora com esses conceitos pois serão reintroduzidos quando houver necessidade de sua aplicação.

Variáveis de instância e métodos no class side

A classe é um objeto. Logo pode possuir também variáveis e métodos de instância que são definidos no seu class side. Voltaremos a isso quando necessário.

Criando e usando objetos de uma classe

Vamos agora "exercitar" a nossa classe e suas instâncias usando o Playground (Veja Como abrir o Playground).

Usando o submenu Do it and go do menu de contexto (acessado com o botão direito do mouse) na primeira expressão obtemos um inspector aberto num painel do lado direito do Playground.

Vemos que a nossa variável de instância balance está com o valor zero que lhe foi atribuido no método initialize em vez do valor default nil.

Experimente inspecionar o resultado das outras expressões.

Troque a primeira expressão por account := Account newWithInitialBalance: 100 e inspecione os novos resultados.

Encerrando

Encerre salvando a imagem.


Report Page