Neste artigo veremos como funciona a herança no mundo Objeto-Relacional Oracle e, principalmente, vamos esclarecer uma das principais dúvidas relativas a este assunto: o uso da cláusula under.

A partir do Oracle 9i, um tipo pode ser estendido criando subtipos que reutilizam a especificação e implementação (atributos e métodos) do tipo que ele deriva. Assim, através dos objetos é possível criar uma hierarquia de tipos (Figura 1). Vale informar que não há suporte à herança múltipla e, sendo assim, um subtipo pode derivar apenas de um único supertipo. Um subtipo se torna um tipo especial de seu pai pelo fato de possuir novos atributos e métodos e também de poder redefinir os que foram herdados. Redefinir métodos dá ao subtipo um estilo próprio de executar esses métodos.

Exemplo de uma hierarquia de tipos
Figura 1. Exemplo de uma hierarquia de tipos

Tipos e métodos FINAL e NOT FINAL

A definição do tipo do objeto determina se um subtipo pode ser derivado. Por padrão os tipos de objeto são do tipo FINAL. Por isso, para permitir subtipos, deve ser obrigatoriamente adicionada à expressão NOT FINAL na declaração do tipo do objeto. Por exemplo, a Listagem 1 apresenta uma expressão onde é declarado que o tipo t_pessoa pode ser derivado, permitindo que sejam criados subtipos a partir dele.

create type t_pessoa as object
(codigo number,
nome varchar2(30),
endereço varchar2(100) ) not final;
Listagem 1. Criação do supertipo t_pessoa

Assim como os tipos de objetos, os métodos também podem ser declarados como FINAL ou NOT FINAL. Se um método for definido como FINAL, os subtipos não podem redefinir sua implementação. Métodos são definidos por padrão como NOT FINAL. O exemplo da Listagem 2 cria um tipo de objeto NOT FINAL contendo uma função definida como FINAL.

create type t as object 
(...,
member procedure imprimir(),
final member function alterar(x number)
... ) not final;
Listagem 2. Criação do tipo t contendo função definida como FINAL

Criação de subtipos

Podemos criar um subtipo usando a declaração CREATE TYPE e especificar o seu supertipo através do parâmetro UNDER. Por exemplo:

create type t_Estudante under t_pessoa
( cod_dep number,
      disciplina_principal varchar2(30) ) not final;

A declaração acima cria um tipo t_Estudante que é subtipo de t_Pessoa. Ele herda todos os atributos e métodos declarados em t_pessoa. São adicionados apenas dois novos atributos com nomes obrigatoriamente diferentes dos nomes e métodos declarados no seu supertipo. Como dito anteriormente, um tipo pode ter múltiplos subtipos, e esses por sua vez também podem ter subtipos. A declaração abaixo cria outro subtipo t_Empregado herdando de t_Pessoa:

create type t_empregado under t_Pessoa
(cod_emp number,
setor varchar2(30));

Criação de tabelas

Pode-se observar que não há estrutura de armazenamento associada com os tipos que pertencem à hierarquia acima descrita. Um object type é apenas um "molde", um tipo; não se pode guardar dados nele. Deve-se então, criar tabelas de objetos para manipular as instâncias dos tipos, formando assim uma hierarquia de tabelas, como ilustra o exemplo da Listagem 3.

create table pessoas of t_pessoa;

create table estudantes of t_estudante
      under t_pessoa;

create table empregados of t_empregado
      under t_pessoa;
Listagem 3. Criação de tabelas com base nos tipos

Mesmo na versão 10 g do Oracle, ainda não foi implementada a cláusula under para criação de tabelas. Ao tentar executar esse comando o usuário deparar-se-á com a seguinte mensagem: “Recurso Não Implementado”. Contudo, já está implementada a hierarquia de views. É possível criar uma subview a partir de uma view como mostra a Listagem 4. Uma subview herda o OID (object identifier) da superview.

CREATE VIEW PessoasV OF t_pessoa WITH OBJECT ID(codigo) AS
SELECT codigo, nome, endereço FROM pessoas;

CREATE VIEW EmpregadosV OF t_empregado UNDER PessoasV AS
SELECT codigo, nome, endereço, setor from empregados;
Listagem 4. Criação de View e Subview

Uma consulta na view PessoasV pode retornar todas as informações de Pessoas e Empregados (Listagem 5).

SELECT Value(p) from PessoasV p;
Listagem 5. Consulta na View PessoasV

O Oracle disponibiliza novos operadores para testar instâncias e converter um supertipo em um subtipo. Na Listagem 6 temos um exemplo de consulta que retorna todas as pessoas que são empregados.

SELECT TREAT(VALUE(p) AS t_empregado)FROM PessoasV p
WHERE VALUE(p) IS OF(t_empregado);
Listagem 6. Consulta na View PessoasV