Na Parte 1 nós vamos tentar decifrar essa sopa de letrinhas, entender o que é down-cast e ver um exemplo simples(só para você não me xingar e dizer que o post é pura teoria).
Não adianta reclamar de siglas amigo cambaleante, você escolheu ser programador. Você poderia ter jogado futebol, basquete, volêi, queimada, peteca… mas já que escolheu ficar aí sentando aguentando usuários chatos, vamos entender o que quer dizer cada uma dessas siglas:
RTTS – Runtime Type Services, ou “Paradas Legais para usar em Tempo de Execução”. Consiste de 2 componentes:
RTTC: Runtime Type Creation: Criação dinâmica em tempo de execução. Ex.: Criar uma nova variável do tipo CHAR 30.
RTTI: Runtime Type Identification: Identificação de tipos em tempo de execução. Ex.: Descobrir que o campo ABC da estrutura WA_XYZ é um CHAR de 20 posições.
Nas minhas pesquisas descobri que, antigamente, só existiam ferramentas para identificação de tipos, que eram chamadas de RTTI. Com o tempo, a SAP implementou ferramentas para criação de variáveis em tempo de execução, e deu o nome de RTTC a elas. Foi então que surgiu a sigla “RTTS”, que serve como identificador para essas ferramentas.
Muita gente fica assustada com RTTS pelo mesmo motivo de sempre: você acessa as ferramentas a partir de uma hierarquia de classes. Falou de SE24 os ABAPossauros tremem, eu sei. Mas vem comigo que a coisa é mais fácil do que parece.
Para acessar qualquer função do RTTS, você precisa utilizar a classe correspondente. O RTTS possui uma hierarquia de classes bem definida, que refletem os tipos e variáveis existentes dentro do SAP (types, estruturas, tabelas internas, objetos, etc). Dê uma olhada neste link, tem um mapa bem legal dos tipos existentes no ABAP.
Você não precisa decorar todas agora, mas é importante saber que essa hierarquia existe na SE24 mais próxima de você:
Para descomplicar um pouco essas siglas de RTTI e RTTC, uma mesma classe possui tanto as funções de descrição quando de criação. Ou seja, se eu quiser fazer alguma coisa (criar/descrever) relacionada a tabelas internas, vou utilizar a classe CL_ABAP_TABLEDESCR.
Sim, este é aquele momento em que você esquece o que RTTI e RTTC querem dizer, e fica só com o RTTS na cabeça. Aí, falei que era fácil 😀 .
Aqui você encontra uma descrição bem detalhada da hierarquia, com seus respectivos métodos RTTIs e RTTCs, além dos atributos de cada classe.
Importante notar que não existe uma classe RTTS específica para cada tipo de variável. Ex.: Todos os tipos de tabelas internas (STANDARD, SORTED, HASHED) podem ser tratados no RTTS pela classe de tabelas CL_ABAP_TABLEDESCR. O resto das classes RTTS também funcionam de forma semelhante.
Em muitos exemplos da internet relacionados a RTTS você vai encontrar o operador ?= , e para não fazer as coisas por osmose, vamos tentar entender um pouco do que essa interrogação se trata.
Antes de mais nada, dê uma lida no post do Mauro falando sobre herança. O conceito de casting está diretamente relacionado aos conceitos de herança.
Este operador serve para que você consiga fazer um down cast, ou seja, para que você consiga mover um objeto de uma classe pai e passar para um outro objeto que faz referência a uma classe filha.
Se eu tiver um objeto do tipo CL_IPHONE, eu irei conseguir enviá-lo a outra variável que faça referência a classe CL_CELULAR. O relacionamento “Iphone é um Celular” é válido (e facilmente compreendido). Como a classe CL_IPHONE é filha de CL_CELULAR, a associação é feita sem problemas, pelo operador “=”. Veja só:
Esse é o chamado up-casting, ou seja: você está enviando um objeto do tipo “filho” para uma variável do tipo “pai”.
Mas e o contrário? E se eu quiser pegar a referencia de CL_IPHONE que está na variável O_CELULAR, e quiser enviar de volta a uma variável do tipo CL_IPHONE?
Aí você fala “ok Mauricio, é bem óbvio que isso funcionaria, certo? Errado! O verificador de sintaxe irá dizer que essa operação não é possível, com uma mensagem que pode parecer absurda: “O_CELULAR não pode ser convertido para o tipo de O_IPHONE“.
Acalme-se jovem zumbiwan. Quem garante que o que está em O_CELULAR é mesmo um O_IPHONE? E se fosse um O_GALAXY? E se fosse um O_LUMIA? E se fosse um O_QUALQUERCELULARDAFACEDATERRA?
É nesse momento que você precisa utilizar o operador ?=. É como se o verificador de sintaxe falasse para você: “eu sei lá o que tem dentro de O_CELULAR, mas já que você tá falando que é um O_IPHONE, eu acredito!”: