Exibir mensagem anterior :: Exibir próxima mensagem |
Autor |
Mensagem |
tiagoshimizu Membro Junior

Registrado: Segunda-Feira, 28 de Setembro de 2009 Mensagens: 329
|
Enviada: Qui Mai 17, 2012 9:26 pm Assunto: Constructor Create em class(TPersistent) [Resolvido] |
|
|
Olá pessoal. Estou com um projeto em que em uma unit tenho o seguinte código:
Código: |
type
{$METHODINFO ON}
TContasReceber = class(TPersistent)
public
destructor Destroy; override;
end;
constructor TContasReceber.Create;
begin
inherited Create;
end;
destructor TContasReceber.Destroy;
begin
inherited Destroy;
end;
|
Tipo, funciona legal ele só que estava precisando implementar uma rotina no Create e daí fui perceber que ele está alí só de enfeite!
Tipo, tentei debugar a aplicação e percebi que nem passa por ele! Fiz a mesma coisa com o destructor e por ele passa! Tentei colocar o override; porem me deu o erro que não se pode implementar o override; pois o constructor não é do tipo virtual. Teria alguma maneira de fazer ele passar pelo create?
Obrigado.
Editado pela última vez por tiagoshimizu em Qui Set 27, 2012 9:41 pm, num total de 1 vez |
|
Voltar ao Topo |
|
 |
felipecaputo Colaborador


Registrado: Quinta-Feira, 13 de Mai de 2010 Mensagens: 1719 Localização: Florianópolis / SC
|
Enviada: Sex Mai 18, 2012 8:55 am Assunto: |
|
|
Olá, para sobrescrever métodos não virtuais você pode utilizar o reintroduce;
Código: | type
{$METHODINFO ON}
TContasReceber = class(TPersistent)
public
constructor Create; reintroduce;
destructor Destroy; override;
end;
constructor TContasReceber.Create;
begin
inherited Create;
end;
destructor TContasReceber.Destroy;
begin
inherited Destroy;
end; |
mas classes descendentes de TPersistent não precisam de override eu acho. Basta declarar o constructor que estava faltando no public e excrever o seu código dentro do create da sua classe
Código: | type
{$METHODINFO ON}
TContasReceber = class(TPersistent)
public
constructor Create;
destructor Destroy; override;
end;
constructor TContasReceber.Create;
begin
inherited Create;
end;
destructor TContasReceber.Destroy;
begin
inherited Destroy;
end; |
tenho um artigo que diz algumas coisas sobre, se quiser conferir http://certificacaodelphi.somee.com/Artigos/artigoVer.aspx?id=17 _________________ if Post.State = psResolvido then
Post.Caption := Post.Caption + ' [RESOLVIDO]';
_____________________________________________
O único homem que está isento de erros, é aquele que não arrisca acertar. Albert Einstein |
|
Voltar ao Topo |
|
 |
tiagoshimizu Membro Junior

Registrado: Segunda-Feira, 28 de Setembro de 2009 Mensagens: 329
|
Enviada: Sex Mai 18, 2012 10:51 am Assunto: |
|
|
felipecaputo, obrigado primeiramente pela resposta. A questão da falta do constructor na clausula public foi falha minha na hora de possar o código para o forum... Também, já havia tentado incluir o reintroduce e não adiantou. Continua não passando pelo create ao debugar! |
|
Voltar ao Topo |
|
 |
felipecaputo Colaborador


Registrado: Quinta-Feira, 13 de Mai de 2010 Mensagens: 1719 Localização: Florianópolis / SC
|
Enviada: Sex Mai 18, 2012 10:59 am Assunto: |
|
|
como o objeto está sendo criado? qual o tipo da variavel que o cria?
os fontes estão no mesmo pacote ou é um pacote diferente e importado apra a aplicação? _________________ if Post.State = psResolvido then
Post.Caption := Post.Caption + ' [RESOLVIDO]';
_____________________________________________
O único homem que está isento de erros, é aquele que não arrisca acertar. Albert Einstein |
|
Voltar ao Topo |
|
 |
JCMF Profissional


Registrado: Quarta-Feira, 28 de Abril de 2010 Mensagens: 578 Localização: Recife, PE
|
Enviada: Sex Mai 18, 2012 11:02 am Assunto: |
|
|
Bom dia amigo!
Sempre que vc for herdar uma classe, os métodos da superclasse, quando permitidos, podem ou devem ser sobrescritos.
O "reintroduce" não é diferente disso... ele apenas determina que a classe final vai possuir uma assinatura diferente da que existe na superclasse, mas o método da superclasse precisa estar marcado para isso, com virtual ou dynamic.
No seu exempo, a superclasse TPersistent herda diretamente de TObject e o construtor Create de TObject não possui implementação alguma e não é virtual ou dynamic. Isso indica que qualquer classe herdada de TObject, direta ou indiretamente, terá o construtor padrão.
Mesmo que você coloque um override ou reintroduce e aplique a palavra reservada inherited no seu construtor Create, nada será feito pois não existe implementação do método na superclasse.
Pelo que vejo, o problema está na sua classe que herda de TPersistent. Pelo Wiki da Embarcadero, isso não é aconselhável:
Citação: | O texto original: "Do not create instances of TPersistent. Use TPersistent as a base class when declaring objects that are not components, but that need to be saved to a stream or have their properties assigned to other objects."
Traduzido: "Não criar instâncias de TPersistent. Use TPersistent como uma classe base ao declarar objetos que não são componentes, mas que precisam ser salvos em um stream ou ter suas propriedades atribuídas a outros objetos." |
A idéia é que a classe TPersistent, e através da sua declaração, para todos os objetos herdados de TObject, não seja instânciada e sim herdada por outras classes.
PS.: Para lhe ajudar nesse sentido, o Delphi disponibiliza dois métodos virtuais na classe TObject, e que estão disponíveis para todas as subclasses, que podem resolver o seu problema. Eles trabalham antes e após a criação padrão e devem ser declarados no nível mais alto de visibilidade "public":
procedure AfterConstruction; virtual;
procedure BeforeDestruction; virtual;
Espero ter ajudado. |
|
Voltar ao Topo |
|
 |
tiagoshimizu Membro Junior

Registrado: Segunda-Feira, 28 de Setembro de 2009 Mensagens: 329
|
Enviada: Sex Mai 18, 2012 11:07 am Assunto: |
|
|
Hummm, entendi. Tipo, no caso então teria de criar uma nova unit "TBase" em que implementaria o constructor Create; herdando este do TPersistent e essa minha unit "TContasReceber" herdando da nova "TBase". Isso? |
|
Voltar ao Topo |
|
 |
JCMF Profissional


Registrado: Quarta-Feira, 28 de Abril de 2010 Mensagens: 578 Localização: Recife, PE
|
Enviada: Sex Mai 18, 2012 11:13 am Assunto: |
|
|
tiagoshimizu escreveu: | Hummm, entendi. Tipo, no caso então teria de criar uma nova unit "TBase" em que implementaria o constructor Create; herdando este do TPersistent e essa minha unit "TContasReceber" herdando da nova "TBase". Isso? |
A idéia seria mais ou menos isso sim amigo!
TPersistent não vai ter override ou reintroduce no seu construtor Create e nem poderá chamar inherited pois não existe implementação na superclasse.
Mas a sua nova classe TBase, por exemplo, poderá ter um construtor Create que será virtual ou dynamic e todos que herdarem direta ou indiretamente dela pode ou deve dar override ou reintroduce do método para novas implementações.
Lembrando que:
override -> Sobrescreve o método da superclasse no seu formato original (Oq muda é a implementação do método)
reintroduce -> Sobrescreve o método da superclasse com alteração da sua assinatura (Mudam a assinatura e a implementação do método) |
|
Voltar ao Topo |
|
 |
JCMF Profissional


Registrado: Quarta-Feira, 28 de Abril de 2010 Mensagens: 578 Localização: Recife, PE
|
Enviada: Sex Mai 18, 2012 11:22 am Assunto: |
|
|
Uma dica boa para estudar implementações de classes do Delphi é acessar sua definição. Isso é possível quando se clica com o botão esquerdo do mouse em cima do nome da classe com a tecla CTRL pressionada.
Isso faz com que o delphi abra a definição da classe e assim, vc poderá ir navegando de classe em classe, subindo para a definição inicial de superclasse e estudar seu comportamento do começo ao fim.
Segurando a tecla CTRL;
Posiciona a seta do mouse no nome da classe que se deseja estudar;
Clica com o botão esquerdo do mouse;
Solta a tecla CTRL.
Fica a dica.
Espero ter ajudado. |
|
Voltar ao Topo |
|
 |
tiagoshimizu Membro Junior

Registrado: Segunda-Feira, 28 de Setembro de 2009 Mensagens: 329
|
Enviada: Sex Mai 18, 2012 11:23 am Assunto: |
|
|
Bom, vamos lá. Criei a nova Unit "BAse" contendo a "TBase" da seguinte forma:
Código: | unit Base;
interface
uses Classes;
type
TBase = class(TPersistent)
public
constructor Create; virtual;
destructor Destroy; override;
end;
implementation
{ TBase }
constructor TBase.Create;
begin
inherited Create;
end;
destructor TBase.Destroy;
begin
inherited Destroy;
end;
end. |
Despois, na minha unit que contem o "TContasReceber" coloquei assim:
Código: |
uses Classes,...., Base;
type
{$METHODINFO ON}
TContasReceber = class(TBase)
private
constructor Create; override;
destructor Destroy; override;
end;
constructor TContasReceber.Create;
begin
inherited Create;
ShowMessage('Agora sim!');
end;
destructor TContasReceber.Destroy;
begin
inherited Destroy;
end; |
Mas também não passou pelo create não! |
|
Voltar ao Topo |
|
 |
JCMF Profissional


Registrado: Quarta-Feira, 28 de Abril de 2010 Mensagens: 578 Localização: Recife, PE
|
Enviada: Sex Mai 18, 2012 2:45 pm Assunto: |
|
|
Boa tarde amigo.
Não sei exatamente oq vc está pretendendo fazer com isso mas, aqui vai algumas explicações sobre o código que vc postou como exemplo:
A nova classe TBase, que está herdando de TPersistent:
Não deve executar o inherited no seu construtor Create pois a superclasse, além de não permitir tal coisa, não possui implementação em seu método.
Perceba que o construtor Create está definido como virtual, permitindo que classes que herdem dela possam sobrescrever o método. Porém, não existe nenhum tipo de implementação nela diferente e com isso, não há necessidade nenhuma de fazer isso. Visto que o construtor será o padrão (Aquele definido em TObject e que não executa nada de especial).
O destrutor Destroy só precisa ser implementado se vc possui alguma coisa a ser executada nesse momento, como um objeto interno da sua classe. Caso isso não aconteça, não é necessário implementar o destrutor Destroy.
Para a sua classe de exemplo, uma correta implementação dessa classe seria algo como abaixo:
Código: | unit Base;
interface
uses Classes;
type
TBase = class(TPersistent)
end;
implementation
{ TBase }
end. |
Só há necessidade de sobrescrever algum método da superclasse se vc pretender realizar alguma codificação adicional nele. Fora isso, não é necessário.
Para a outra classe, que está herdando de TBase:
Os métodos construtor e destrutor Create e Destroy devem, sempre, estar definidos no mais alto nível de visibilidade "public". Eles até podem ficar em outro nível quando algumas situações exigem tal procedimento mas, no seu caso, isso não é necessário.
O construtor Create, agora, possui uma implementação diferenciada que é o ShowMessage e por isso, deve ser sobrescrito.
Atente para que a execução dessa mensagem só será feita quando a classe TContasReceber for instanciada e nunca em nenhuma outra situação.
Novamente, não há necessidade de implementar o destrutor Destroy pois nada está sendo executado nele que exija tal coisa.
Código: | uses Classes,...., Base;
type
{$METHODINFO ON}
TContasReceber = class(TBase)
public
constructor Create; override;
end;
constructor TContasReceber.Create;
begin
inherited Create;
ShowMessage('Agora sim!');
end;
end; |
Espero ter ajudado. |
|
Voltar ao Topo |
|
 |
RodrigoFarias Experiente


Registrado: Domingo, 27 de Julho de 2008 Mensagens: 443
|
Enviada: Sex Mai 18, 2012 5:23 pm Assunto: |
|
|
@tiagoshimizu, como você está instanciando sua classe?
Coloca o código fazendo favor.
Realmente não entendi o que está acontecendo. Simplesmente quer fazer ações no construtor do sua classe herdada ?
Algo como:
Código: |
TClassTest = class(TPersistent)
constructor Create;
end;
constructor TClassTest.Create;
begin
ShowMessage('Chegou');
end;
|
Funciona normal.
Att. _________________
Novo Find Uses Para Delphi - https://github.com/rfrezino/RFindUnit |
|
Voltar ao Topo |
|
 |
tiagoshimizu Membro Junior

Registrado: Segunda-Feira, 28 de Setembro de 2009 Mensagens: 329
|
|
Voltar ao Topo |
|
 |
tiagoshimizu Membro Junior

Registrado: Segunda-Feira, 28 de Setembro de 2009 Mensagens: 329
|
|
Voltar ao Topo |
|
 |
|