Método Abstrato
Olá, estou desenvolvendo uma hierarqui de classes, e estou definindo um méto abstrato. Acontece que eventualmente as classes descendentes podem não implementar este método. Gostaria de saber como se certificar que este método foi definido.
Grato,
Grato,
TClassePai = class ... function MetodoAbstrato: Boolean; abstract; virtual ... end; TClasseFilho = class(TClassePai) ... //Não implementei a function MetodoAbstrato; ... end; ... ... ... procedure Qualuer; var objs : array of TClassePai; begin ... objs[0] := TClasseFilho.Create(...); ... if (TClassePai(objs).MetodoAbstrato) then begin //Vai dar erro, quero conferir se MetodoAbstrado está implementado end; end;
Marioguedes
Curtidas 0
Respostas
Marco Salles
11/04/2005
Se voce definir uma variavel do tipo TClassePai
e querer Acessar o [b:2334e448b9]MétodoAbstract é claro que ira dar erro[/b:2334e448b9] :cry: :cry: :cry:
A Palavra Chave[b:2334e448b9] <abstract>[/b:2334e448b9] e usada para declara métodos que serão definidos apenas nas [b:2334e448b9]subclasses[/b:2334e448b9] da classe atual
entao vejamos o exemplo:
Podemos por [b:2334e448b9]regra[/b:2334e448b9] usar um objeto de uma classe descendende sempre que um objeto de uma classe ancestral for esperado..
Assim podemos fazer:
Agora sim , podemos Chamar o Método FunctionAbstracto
que nao iremos ter erro
Agora vamos ao caso de voce não implementar este método definido na classe ascendende na subclasse... [size=14:2334e448b9][color=red:2334e448b9][b:2334e448b9]Isto não faz sentido [/b:2334e448b9][/color:2334e448b9][/size:2334e448b9] :cry: :cry: :cry: :cry:
Agora vamos ao caso de voce [b:2334e448b9]ter definido [/b:2334e448b9]o método na subClasse então em RunTime voce deve usar o operador [b:2334e448b9]Is ou As [/b:2334e448b9]Para ver qual a classe Progenitora do Objeto
em outra palavras ó operador is é [b:2334e448b9]avaliada[/b:2334e448b9] como [b:2334e448b9]true[/b:2334e448b9] somente se o Objeto tiver se referindo a um objeto da ClasseFilho
e querer Acessar o [b:2334e448b9]MétodoAbstract é claro que ira dar erro[/b:2334e448b9] :cry: :cry: :cry:
//Vai dar erro, quero conferir se MetodoAbstrado está implementado
A Palavra Chave[b:2334e448b9] <abstract>[/b:2334e448b9] e usada para declara métodos que serão definidos apenas nas [b:2334e448b9]subclasses[/b:2334e448b9] da classe atual
entao vejamos o exemplo:
var obj : TClassePai
Podemos por [b:2334e448b9]regra[/b:2334e448b9] usar um objeto de uma classe descendende sempre que um objeto de uma classe ancestral for esperado..
Assim podemos fazer:
obj:=TClasseFilho.Create
Agora sim , podemos Chamar o Método FunctionAbstracto
que nao iremos ter erro
Obj.MetodoAbstrato
Agora vamos ao caso de voce não implementar este método definido na classe ascendende na subclasse... [size=14:2334e448b9][color=red:2334e448b9][b:2334e448b9]Isto não faz sentido [/b:2334e448b9][/color:2334e448b9][/size:2334e448b9] :cry: :cry: :cry: :cry:
Agora vamos ao caso de voce [b:2334e448b9]ter definido [/b:2334e448b9]o método na subClasse então em RunTime voce deve usar o operador [b:2334e448b9]Is ou As [/b:2334e448b9]Para ver qual a classe Progenitora do Objeto
if Obj is TClasseFilho Then obj.MetodoAbstrato
em outra palavras ó operador is é [b:2334e448b9]avaliada[/b:2334e448b9] como [b:2334e448b9]true[/b:2334e448b9] somente se o Objeto tiver se referindo a um objeto da ClasseFilho
GOSTEI 0
Marioguedes
11/04/2005
Marco Salles, estou ciente das caracteristicas do meu projeto.
Suas respostas estão tecnicamente perfeitas.
O meu problema é que vou dar uma classe para cada programador da minha equipe desenvolver e cada classe tem um comportamento específico, quero me proteger de eventuais erros.
Se não houver alternativa melhor, vou usar um try except.
Mas de qualquer forma muito obrigado por sua avaliação.
Suas respostas estão tecnicamente perfeitas.
O meu problema é que vou dar uma classe para cada programador da minha equipe desenvolver e cada classe tem um comportamento específico, quero me proteger de eventuais erros.
Se não houver alternativa melhor, vou usar um try except.
Mas de qualquer forma muito obrigado por sua avaliação.
function TMCTAcaoBase.Executar: Boolean; begin if (Log <> nil) then Log.Lines.Insert(0,Self.Nome); try Result := Self.ExecutarAcao; Result := True; except on E : Exception do begin Log.Lines.Add(´(´ + E.ClassName + ´) - ´ + E.Message); Result := False; end; end; end;
GOSTEI 0
Beppe
11/04/2005
marioguedes, vc está usando 1 de 3 soluções.
1) Verificar a exceção EAbstractError
2) Não marcar o método com abstract. Faça a função retornar False, se for o caso.
3) A RTL o Delphi 7 usa um truque para lidar com as versões de 32 e 64 bits de TStream(vide TStrem.Seek). Se uma for abstrata, chama a outra.
Fica a seu critério a escolha, é questão de estilo.
1) Verificar a exceção EAbstractError
2) Não marcar o método com abstract. Faça a função retornar False, se for o caso.
3) A RTL o Delphi 7 usa um truque para lidar com as versões de 32 e 64 bits de TStream(vide TStrem.Seek). Se uma for abstrata, chama a outra.
var Base, Impl: function(Offset: Longint; Origin: Word): Longint of object; B, I: TStream; begin // esta versão checa os métodos de 32 bits, que deve // prosseguir com a execução do programa // a versão de 64 bits chamaria Halt B := TStream.Create; I := TMemoryStream.Create; Base := B.Seek; Impl := I.Seek; if TMethod(Base).Code = TMethod(Impl).Code then Halt; end;
Fica a seu critério a escolha, é questão de estilo.
GOSTEI 0
Massuda
11/04/2005
Olá, estou desenvolvendo uma hierarqui de classes, e estou definindo um méto abstrato. Acontece que eventualmente as classes descendentes podem não implementar este método. Gostaria de saber como se certificar que este método foi definido.
Normalmente o que se faz no caso da implementação de um método virtual ser opcional em uma classe derivada/filha é a classe base/pai definir uma implementação padrão desse método (uma procedure que não faz nada ou uma function que retorna um valor fixo).Normalmente quando se usa um método virtual abstrato em uma classe base isso significa que obrigatoriamente todas as classes derivadas devem implementar esse método.
GOSTEI 0
Marioguedes
11/04/2005
Um amigo localizou esta matéria para mim, basicamente o ponteiro não pode ser nulo - simples assim.
[url]http://www.delphibasics.co.uk/RTL.asp?Name=AbstractErrorProc[/url]
[url]http://www.delphibasics.co.uk/RTL.asp?Name=AbstractErrorProc[/url]
GOSTEI 0
Massuda
11/04/2005
Um amigo localizou esta matéria para mim, basicamente o ponteiro não pode ser nulo...
AbstractErrorProc é uma variável que define qual procedure do seu programa irá ser executada quando ocorrer um erro por tentar executar um método abstrato. Isso não evita que seu programa execute métodos abstratos, apenas esconde o erro.GOSTEI 0