Mostrar um método Protegido ao mundo externo como?

Delphi

04/05/2005

Pessoal,


O que quero fazer é o que a Borland chama de ´surface property´, mas com métodos.

Assim: tenho uma classe pai que tem TODOS os métodos como protegido. Tem como na classe filha eu colocar esses métodos que no pai são protegidos com a visibilidade pública?

Gostaria de fazer igual com propriedades, e não precisar declarar eles na seção pública e dar override em todos os métodos. Tem como ?

Obrigado.

Yalle Cunha.


Yallebr

Yallebr

Curtidas 0

Respostas

Faelcavalcanti

Faelcavalcanti

04/05/2005

Dessa forma você estaria quebrando o conceito de O.O pois mesmo que você atribuísse um método protegido à classe pai, a filha teria total visibilidade e não outras classes mesmo que sejam de outros pacotes e assim como outros projetos. Existem diversos design patterns de aplicação para resolver assuntos sobre tipos de visibilidades aplicados. O que viria em mente para se poder fazer isso, mas sobre ´surface property´ nunca ouvi falar, e também gostaria de saber sobre o assunto. Obrigado!!!


GOSTEI 0
Yallebr

Yallebr

04/05/2005

faelcavalcanti,


A questão de quebrar o conceito OO, acho que não estaria fazendo isso. Pois o Delphi permite que eu faça isso com propriedades. Até com método. Mas com método eu tenho que redeclarar o método no público e chamar o inherited apenas (não quero fazer isso), eu quero fazer isso igual com propriedades. Apenas adicionando as assinaturas.

property MultaReal; Isso eu estaria vendo a propriedade que é protegida no pai e publicando (published) no filho.


GOSTEI 0
Marco Salles

Marco Salles

04/05/2005

Eu nao sei se entendi bem a sua pergunta... :arrow: Mas acho que voce na realidade, quer acessar os [b:49918950f7]dados Protegidos [/b:49918950f7]de uma classe em Outra Unit... Porque na unit que foi definido , é claro que se consegue acessar :lol: :lol:

Olhe , se existe algum jeito , de alterar esta definição , eu particurlamente não conheço. :cry: . Mas para acessar dados Protegidos de Uma determinada classe , :idea: nen precisa torna-los publicos na classe filha...

:wink: Basta Fazer uma[b:49918950f7] conversão do tipo do objeto [/b:49918950f7]na nova Classe e acessar os dados Protegidos atravez dela...

Vamos ao Exemplo:

Suponha que voce tenha declarado uma classe pai

Type 
  Ttest = Class
  protected
    ProtecTedData:Integer;
  public
    PublicData:Integer;
    Function GetValue:String;
end;


[b:49918950f7][color=darkred:49918950f7]Com fazer para acessar a propriedade ProtecttedData ?? com torna-la Visivel???[/color:49918950f7][/b:49918950f7]

Olhe para a Definição da classe filha

suponha que se tenha definido uma simples classe filha , em uma outra unit..Esta classe filha pode ser a mais simples ..

o Macete e fazer uma conversão do tipo do objeto na nova classe e acessar os dados protegidos atraves dela. Por exemplo:

var 
 obj:TTest;
begin
  obj:=TTest.Create;
 //obj.ProtectedData:=20; --->> Não compila ....Fazer a conversão
  TFake(Obj).ProtectedData:=20; //acessando os dados
  obj.Free;


O grande macete é a chamada que se faz...


GOSTEI 0
Yallebr

Yallebr

04/05/2005

Marco Salles,

Obrigado pela resposta.
O que vc falou realmente funciona. Mas não seria isso q eu queria. Eu querio assim.

TPai = class
private
  FResultado: Float;
protected
  procedure Contar;
  property Resultado: Float read FResultado write FResultado;
end;

TFilho = class(TPai)
public
  property Resultado; ----> isso funcionado.
  //queria fazer isso.
  procedure Contar; override. (mas sem precisar implementar o método, igual a propriedade
end;




GOSTEI 0
Marco Salles

Marco Salles

04/05/2005

TPai = class 
private 
  FResultado: Float; 
protected 
  procedure Contar; 
  property Resultado: Float read FResultado write FResultado; 
end; 

TFilho = class(TPai) 
public 
  property Resultado; ----> isso funcionado. 
  //queria fazer isso. 
  procedure Contar; override. (mas sem precisar implementar o método, igual a propriedade 
end; 



GOSTEI 0
Marco Salles

Marco Salles

04/05/2005

Apertei o Botão sem terminat minha colocação :oops: :oops: :oops:

TPai = class 
private 
  FResultado: Float; 
protected 
  procedure Contar; 
  property Resultado: Float read FResultado write FResultado; 
end; 

TFilho = class(TPai) 
public 
  property Resultado; ----> isso funcionado. 
  //queria fazer isso. 
  procedure Contar; override. (mas sem precisar implementar o método, igual a propriedade 
end; 


Quase que absoluta certeza , que , campos e métodos Definidos com a directiva Private Não Podem se acessados Fora da Unidade onde esta declarado a Classe

Agora , campos e métodos , definidos com a directica Protected Tem a visibilidade Limitada e podem, [b:5c145af1b2]usando a correta conversão [/b:5c145af1b2], serem acessadas Fora da Unidade que a declara...

:arrow: Geralmente , o padrão é , campos de uma classe usando a directiva Private e métodos que acessam esse campos usando a directiva Public

Na sua definição da classe pai , voce deve [b:5c145af1b2]redefinir[/b:5c145af1b2]

unit Unit2;

interface

type
TPai = class
private
  FResultado:Real;
  Function GetResultado:Real;
  procedure SetResultado(const Value: Real);
public
  property Resultado: Real read FResultado write FResultado;
end;


implementation

{ TPai }


function TPai.GetResultado: Real;
begin
 result:=FResultado;
end;

procedure TPai.SetResultado(const Value: Real);
begin
 FResultado:=Value;
end;



Com isto voce Torna ´publico´ o Valor de Resultado e na classe filha ;
Voce consegue agora:

type
 TFilho = Class(TPai);
...............
var
 obj:TFilho;
Begin
 obj.Create;
 Obj.Resultado:=20;
  showmessage(FloatToStr(Obj.Resultado));
 obj.Free;
end;


Serai isto :?: :?: :?: :?:


GOSTEI 0
Yallebr

Yallebr

04/05/2005

Não.

O que vc fez funciona, pois ele está declarado como público no método do pai.

type TPai = class private FResultado:Real; Function GetResultado:Real; procedure SetResultado(const Value: Real); public [b:24cdd4a3ed] property Resultado: Real read FResultado write FResultado; [/b:24cdd4a3ed] end;


Agora vamos supor que tenho o método contar no protegido do pai. Eu quero colocar no publico do filho. Igual vc faria com uma propriedade. APenas redeclarando ele no filho no local onde desejo. Assim

type 
TPai = class 
private 
  FResultado:Real; 
  procedure Contar;
public 
  property Resultado: Real read FResultado write FResultado; 
end; 

TFIlho = class(TPai)
public
  procedure Contar; override; (ou qualquer outra diretiva que permita)
  ---> Isso não funciona. Pois preciso imprementar o método. E eu não quero implementar o método, ele é 100¬ igual ao do pai, ele muda apenas a visibilidade dele. Entendeu?
end;




GOSTEI 0
Beppe

Beppe

04/05/2005

Não tem como só redeclarar...o que vc pode fazer e declará-lo como púclico e na sua implementação chamar o método do pai.


GOSTEI 0
Marco Salles

Marco Salles

04/05/2005

Agora vamos supor que tenho o método contar no protegido do pai.


Eu quero colocar no publico do filho.


APenas redeclarando ele no filho no local onde desejo. Assim


Não tem como só redeclarar...o que vc pode fazer e declará-lo como púclico e na sua implementação chamar o método do pai.

[color=red:12c275ed34][b:12c275ed34]Isto é Ponto....[/b:12c275ed34][/color:12c275ed34]

Pois preciso imprementar o método. E eu não quero implementar o método, ele é 100¬ igual ao do pai, ele muda apenas a visibilidade dele. Entendeu?


[color=red:12c275ed34][color=red]Isto é outro Ponto[/color:12c275ed34][/color]

[b:12c275ed34]Mude a directiva de Private para Protected e use a conversão[/b:12c275ed34]


GOSTEI 0
Yallebr

Yallebr

04/05/2005

Marco Salles e Beep,


Obrigado.
Beep, seria isso mesmo que eu queria.. Eu cheguei a conslusão que não da. Queria ver isso com vc´s antes de formular uma opniao final.

8)


GOSTEI 0
Beppe

Beppe

04/05/2005

Marco Salles e Beep, Obrigado. Beep, seria isso mesmo que eu queria.. Eu cheguei a conslusão que não da. Queria ver isso com vc´s antes de formular uma opniao final. 8)

A propósito, lembre de colocar o [b:289ab63457]inherited[/b:289ab63457] na frente, se for usar exatamente o mesmo nome.


GOSTEI 0
POSTAR