É muito provável que eventualmente você já tenha visto Interfaces na implementação de algumas coisas no Unity, como controle de joystick ou sobrecarga na criação de alguma struct ou classe.
Em minhas aulas, é recorrente o uso quando preciso implementar algumas ações de objetos distintos.
Nessa aula, complementarei o estudo de programação de jogos, trazendo minha visão sobre Interface, e auxiliarei você a entender melhor o contexto de Interface, quando se deparar com uma.
Herança em POO
Para entender Interface é altamente recomendável, como conhecimento prévio, entender POO.
Em POO, criamos uma classe para abstrair um conjunto de objetos a partir de atributos e ações semelhantes. Por exemplo, uma classe Carro abstrai um conjunto de objetos que possuem quatro assentos, portas, rodas, motor, etc..
Quando criamos uma classe Automóvel, podemos abstrair um conjunto de objetos que possuem assento, método de locomoção e controle, combustível, etc..
Com a classe Automóvel, usamos a classe Carro como especialista dela, ou seja, Automóvel abstrai uma ampla gama de objetos e usamos a classe Carro para delimitar um subconjunto em automóveis. Fazemos isso para separar os atributos e métodos específicos de Carro, e implementar essas especificidades.
Veja que a relação entre as classes é uma relação hierárquica, pois Carro é subconjunto de Automóvel (carro é um dos vários outros tipos de automóvel), e, portanto, a herança que carro estabelece com automóvel faz todo sentido por causa dessa relação.
Agora vamos para outro exemplo. Imagine um jogo que contém objetos interagíveis, como porta, alavanca, interruptor. Se fossemos organizar esses objetos em uma estrutura de classe, como faríamos?
Poderíamos criar uma classe para cada tipo de objeto interagível, mas toda vez que o jogador fosse interagir com eles, teria que verificar qual é o objeto em questão e disparar sua ação:
Ai você pode imaginar como seria um jogo com 30, 50 ou até mais tipos de objetos interagíveis diferentes - um if para cada um. Seria inviável.
Outra solução poderia ser criar uma classe Interactable para implementar esses objetos, o problema é que cada um funciona de uma forma diferente.
Você pode argumentar falando em implementar classes especialistas da Interactable para cada objeto diferente, e é até uma boa ideia, mas qualquer mudança estrutural na classe Interactable força uma mudança nas classes filhas. Além disso, conceitualmente a abstração feita pela Interactable é uma abstração muito fraca para uma relação hierárquica, porque apenas ser interagível diz muito pouco sobre o que é e o que faz o objeto, porque na prática pode ser qualquer coisa.
A melhor opção seria então transformar a classe Interactable em uma Interface. Podemos elencar as diferenças para você entender o motivo:
Classes se baseiam na abstração de objetos, e esses objetos são descritos pelo todo, atributos e métodos. Assim, quando submetidos a uma hierarquia, eles precisam respeitar as definições do que vem antes - atributos e métodos definidos pelas classes superiores - , e, em certa medida, obrigatoriamente executar tais métodos do jeito que foram definidos nessas classes. Isso simboliza uma hierarquia rígida, pouco flexível.
Interfaces, ao contrário das classes, discriminam métodos que um objeto pode executar. Eles não partem da abstração de um conjunto de objetos, mas sim de métodos. Além disso, Interface, em geral, não implementa nada, apenas determina que objetos herdeiros dela implementem tais métodos ao seu próprio modo. Por esses dois motivos, Interface define uma relação fraca (quando comparada a uma classe).
Ao transformar a classe Interactable em interface, essa nova interface apenas diz que um objeto interagível possui um método Interact(). O que ele faz e como ele faz se torna uma questão exclusiva dos códigos de cada objeto, e, quando o personagem precisar interagir, ele não precisará saber nada sobre isso, apenas saberá que deve rodar o método Interact(), pois visualizará apenas a interface:
Veja que dessa forma não é necessário saber quem é o objeto, apenas sabemos que é um objeto interagível.
Para não alongar o tutorial, implementaremos, em detalhe, o contexto de uso da Interface na próxima parte.