iOS e Swift: Como funcionam os modificadores de acesso

iOS e Swift: Como funcionam os modificadores de acesso
Giovanna Moeller
Giovanna Moeller

Compartilhe

Resumindo

Neste artigo, vamos entender como funciona o controle de acesso no Swift. Veremos também:

  • O que são as palavras open, public, internal, fileprivate e private;
  • Quando utilizar cada uma delas;
  • No que elas interferem no nosso código.

Depois de ler esse artigo, você vai conseguir compreender mais sobre como funciona o acesso de partes do seu código por outras partes do seu código e quando utilizar cada nível de acesso. Vamos lá?

Banner promocional da Alura, com um design futurista em tons de azul, apresentando dois blocos de texto, no qual o bloco esquerdo tem os dizeres:

Módulos e arquivos fonte

Antes de entrarmos no assunto de controle de acesso e seus modificadores, é importante saber que esses recursos são baseados em módulos e arquivos fonte (source files). Por isso, primeiro devemos entender esses conceitos.

Quando estamos criando uma aplicação iOS, podemos utilizar uma biblioteca externa, ou até mesmo um framework. E, para importar essa biblioteca, usamos a palavra-chave import, certo?

E, agora, você sabia que essa biblioteca funciona como um módulo?

Pois é! Um módulo é uma unidade única de distribuição do código - um framework ou aplicativo que é construído e enviado como uma única unidade e que pode ser importado por outro módulo com a palavra-chave de importação do Swift, a import. Portanto, quando importamos uma biblioteca, por exemplo, a Alamofire, nós estamos importando um módulo para nossa aplicação.

Em um projeto, podemos ter vários módulos (no mínimo, sempre haverá um módulo). O projeto, a aplicação em si, é um módulo. E se a gente criar testes para essa aplicação, por exemplo, isso será considerado um outro módulo.

Ou seja, cada build target no XCode é tratado como um módulo no Swift. Target significa alvo, destino, e cada projeto contém pelo menos um target, que especifica uma aplicação para buildar ou construir. Vamos ver um exemplo de um projeto chamado "AlamofireTest":

Imagem que mostra a tela do XCode. No lado esquerdo da tela, há uma lista com projetos e targets da aplicação. No primeiro título, “project”, há a aplicação “AlamofireTeste”. Abaixo, a lista dos targets, que são dois: AlamofireTest e AlamofireTestTests.

Na imagem acima, o XCode mostra os dois targets do nosso projeto: "AlamofireTest" (que é a aplicação), e os testes unitários para essa aplicação ("AlamofireTestTests").

Um arquivo fonte (ou também arquivo de origem, chamado source file) é um arquivo de código-fonte Swift (com a extensão .swift) dentro de um módulo. Entendido isso, vamos agora explorar mais sobre o controle de acesso e seus modificadores!

Entendendo o que é controle de acesso

Você pode estar se perguntando: "o que seria o controle de acesso?". É um recurso que nos permite, como desenvolvedores, restringir ou permitir o acesso a algumas partes do código que estamos desenvolvendo.

Com ele, você pode impedir facilmente a implementação de alguma funcionalidade, por exemplo, caso você queira que essa funcionalidade não seja acessada por nenhuma outra parte do código. Ou, até mesmo, deixá-la pública para ser visível e acessada por todo o projeto.

No Swift, o controle de acesso possui cinco palavras-chave diferentes que podem ser usadas em classes, structs, enumerations, ou até mesmo em inicializadores, propriedades e métodos. Essas palavras-chave são chamadas de modificadores de acesso. Vamos ver mais sobre elas a seguir.

E os modificadores de acesso?

Como dito acima, temos cinco palavras-chave que são os modificadores de acesso. Esses modificadores, portanto, definem o nível de acesso de determinada parte do seu código. Esses níveis de acesso são relativos ao arquivo de origem no qual uma entidade é definida e também ao módulo ao qual o arquivo de origem pertence.

Chamamos de "entidade" aquilo que possui um modificador de acesso, podendo ser uma class, struct, enum, ou até mesmo inicializadores, propriedades e métodos.

Veja abaixo quais são esses modificadores de acesso e entenda a seguir qual a funcionalidade de cada um deles:

  • open;
  • public;
  • internal;
  • fileprivate;
  • private.

Essa é a ordem dos modificadores de nível menos restritivo (no topo) para o mais restritivo.

1) Open

Esse modificador é o menos restritivo de todos, pois permite que qualquer entidade que tenha sido declarada com esta palavra-chave seja usada em qualquer lugar dentro do módulo atual. Esta entidade também pode ser usada em outros módulos, contanto que o módulo contendo a entidade seja importado nos outros módulos.

Entretanto, esse modificador só pode ser utilizado em classes e membros dessa classe. Membros de uma classe significa propriedades e métodos, ou seja, tudo que uma classe contém, mas não podem ser colocados em structs, enumerations, etc.

Você também pode ter um open na subclass (classes que possuem o conceito de herança) ou também sobrescrever um método open (esse conceito é chamado de override) tanto no módulo atual quanto em outro módulo que importe esse em que está definido a entidade.

Basicamente, isso significa que, se alguém importa algum módulo para outro, pode usar as classes marcadas como open ou também as subclasses marcadas como open.

Esse modificador, junto com o public, é muito utilizado em frameworks, já que possui todo o conceito de abrir uma entidade para ser utilizada em qualquer outro módulo.

2) Public

É praticamente idêntico ao modificador open, permitindo o mesmo acesso, porém com algumas diferenças. Podemos usar o modificador public em outros tipos além de classes, como structs ou enumerations.

Além disso, não podemos utilizá-lo em subclass (classes que possuem o conceito de herança) ou sobrescrever métodos declarados com public em outros módulos, diferente do modificador open, que permite isso.

3) Internal

Esse modificador permite o acesso ao código de qualquer lugar no módulo atual, mas não fora dele.

O modificador de acesso padrão, caso não definirmos um, é o internal. Isso significa que o código do módulo que você escreveu é acessível por todos os arquivos de origem desse mesmo módulo.

O Swift, além de oferecer diversos níveis de controle de acesso, reduz a necessidade de especificar níveis de controle de acesso explícito, fornecendo algo padrão para cenários típicos.

4) Fileprivate e Private

Esse modificador permite o uso da entidade somente dentro do arquivo de origem definido. Enquanto o modificador private permite o uso apenas dentro da entidade definida, o fileprivate permite o uso dentro do arquivo onde essa entidade foi definida.

Veremos mais sobre esse modificador junto com o private, logo abaixo.

O private é o nível mais restritivo de todos, restringindo o uso de uma entidade. Private é usado quando você precisa ocultar detalhes de implementação de alguma funcionalidade usada dentro de uma única entidade.

Vamos criar uma classe chamada Pessoa e atribuir algumas propriedades para ela:

class Pessoa {
  var nome: String
  var email: String

  init(nome: String, email: String) {
    self.nome = nome
    self.email = email
  }

}

E então, criar uma variável para instanciar essa classe chamada "Pessoa":

var pessoa1 = Pessoa(nome: "Giovanna", email: "[email protected]")
print(pessoa1.nome) // "Giovanna"
print(pessoa1.email) // "[email protected]"

Agora, não queremos que essa variável email seja visível fora dessa struct. Como podemos fazer isso? Adicionando o modificador de acesso private antes de declarar a propriedade. Olhe só:

class Pessoa {
  var nome: String
  private var email: String

  init(nome: String, email: String) {
    self.nome = nome
    self.email = email
  }
}

Se quisermos acessar a propriedade email de uma instância, não conseguimos. Irá causar um erro dizendo que a propriedade email é inacessível por causa do seu nível de proteção private (privado). Ou seja, essa propriedade só consegue ser acessada dentro da classe.

Caso a gente mude de private para fileprivate, nós conseguimos acessar a propriedade email, desde que esse acesso seja feito no mesmo arquivo onde essa classe está definida. Então supondo que essa classe, junto com as instâncias, estejam dentro de um arquivo "Pessoa.swift", então conseguimos acessar essa propriedade sem problemas.

Porém, caso a classe seja criada num arquivo diferente de onde criamos as instâncias, essa propriedade não pode ser acessada.

Agora, deu para entender um pouco melhor sobre os modificadores de acesso e qual a funcionalidade de cada um?

Conclusão

Nesse artigo, entendemos mais sobre o controle de acesso e seus modificadores, quais são eles e suas funcionalidades. Também vimos os conceitos de módulos e arquivos fonte.

Você também pode complementar seus estudos lendo mais sobre na documentação.

Se você tem interesse em outros artigos ou quer conhecer mais sobre o desenvolvimento iOS, basta me procurar aqui: Linkedin.

Quer saber mais sobre iOS? Confira nosso curso para iniciantes aqui na Alura: Swift parte 1 - Desenvolvendo para iOS no Xcode.

Até a próxima!

Giovanna Moeller
Giovanna Moeller

Desenvolvedora de Software e Criadora de Conteúdo @girl.coding

Veja outros artigos sobre Mobile