a mesma coisa em pascal:
type
Lutador = interface
function estaVivo : boolean;
function forcaDeAtaque : Integer;
function nome : string;
function numeroDeVidasAtual : Integer;
procedure registrarObservador(observador : ObservadorDaLuta);
end;
[code]unit uJogador;
interface
uses
uLutador, Classes, SysUtils;
type
Jogador = class(TInterfacedPersistent, Lutador)
private
numeroDeVidas : Integer;
fArma : TArma;
fTesouro : TTesouro;
armadura : TArmadura;
Fnome : string;
observador : ObservadorDaLuta;
estrategiaDeCombate : TEstrategiaDeCombate;
public
const efetividadeDoGolpe = 80;
private
procedure reiniciarNumeroDeVidas;
procedure levantarExcecaoParametroNulo(parametro : TObject; nomeDoParametro : string);
public
constructor Create(nome : string); reintroduce;
destructor Destroy; override;
procedure beberPocaoDeVida;
procedure golpeRecebido(inimigo : TInimigo; golpe : TGolpe);
procedure golpear(inimigo : TInimigo);
procedure definirEstrategiaDeCombate(estrategia : EstrategiaDeCombate);
function segurarArma(arma : TArma) : TArma;
function vestirArmadura(armadura : TArmadura) : TArmadura;
public
function estaVivo: Boolean;
function forcaDeAtaque: Integer;
function nome: string;
function numeroDeVidasAtual: Integer;
procedure registrarObservador(observador: TObject);
function segurarTesouro(Tesouro : TTesouro) : TTesouro;
public
property Arma : TArma read fArma;
property Tesouro : TTesouro read fTesouro;
end;
implementation
{ Jogador }
constructor Jogador.Create(nome : string);
begin
if Trim(nome) = ‘’ then
levantarExcecaoParametroNulo(nil, ‘O campo nome não pode ser nulo’);
inherited Create;
fArma := TArma.Create(TipoDeArma.FACA);
fTesouro := null;
armadura := TArmadura.Create(TipoDeArmadura.NENHUMA);
fNnome := nome;
reiniciarNumeroDeVidas;
end;
destructor Jogador.Destroy;
begin
fArma.Free;
armadura.Free;
inherited;
end;
procedure Jogador.reiniciarNumeroDeVidas;
begin
numeroDeVidas := 10;
end;
procedure Jogador.levantarExcecaoParametroNulo(parametro: TObject;
nomeDoParametro: string);
begin
if parametro = nil then
raise Exception.CreateFmt(‘O parâmetro %s não pode ser nulo!’, [nomeDoParametro]);
end;
procedure Jogador.beberPocaoDeVida;
begin
if tesouro is TPocaoDeVida then
begin
reiniciarNumeroDeVidas;
tesouro := nil;
end;
end;
procedure Jogador.golpeRecebido(inimigo : TInimigo; golpe : TGolpe);
var
danoCausado : Integer;
begin
levantarExcecaoParametroNulo(inimigo, ‘inimigo’);
levantarExcecaoParametroNulo(golpe, ‘golpe’);
danoCausado := golpe.danoQueCausa - armadura.tipo.nivelDeProtecao;
if danoCausado < 0
danoCausado = 0;
Dec(numeroDeVidas, danoCausado);
if observador <> nil then
observador.notificarContraAtaqueRecebido(inimigo, golpe, danoCausado);
end;
procedure Jogador.golpear(inimigo : TInimigo);
var
golpe : TGolpe;
begin
levantarExcecaoParametroNulo(inimigo, ‘inimigo’);
if not estaVivo()) then
raise IllegalStateException.Create(‘Operação illegal quando se está morto’);
if estrategiaDeCombate = nil then
raise ExcecaoEstrategiaNaoDefinida.Create(’’);
golpe := estrategiaDeCombate.gerarGolpe(self);
inimigo.golpeadoPor(Self, golpe);
end;
procedure Jogador.definirEstrategiaDeCombate(estrategia : EstrategiaDeCombate);
begin
levantarExcecaoParametroNulo(estrategia, ‘estrategia’);
estrategiaDeCombate = estrategia;
end;
function Jogador.segurarArma(arma : TArma) : TArma;
begin
levantarExcecaoParametroNulo(arma, ‘arma’);
if arma.tipo.danosQueElaCausa > Self.arma.tipo.danosQueElaCausa() then
begin
Result = Self.arma;
Self.arma = arma;
end else
Result = arma;
end;
function Jogador.vestirArmadura(armadura : TArmadura) : TArmadura;
begin
levantarExcecaoParametroNulo(armadura, ‘armadura’);
if armadura.tipo.nivelDeProtecao > Self.armadura.tipo.nivelDeProtecao then
begin
Result := Self.armadura;
Self.armadura := armadura;
end else
Result := armadura;
end;
function Jogador.estaVivo: Boolean;
begin
result := numeroDeVidas > 0;
end;
function Jogador.forcaDeAtaque: Integer;
begin
Result := 2 + arma.tipo.danosQueElaCausa;
end;
function Jogador.nome: string;
begin
Result := Self.nome;
end;
function Jogador.numeroDeVidasAtual: Integer;
begin
Result := numeroDeVidas;
end;
procedure Jogador.registrarObservador(observador: TObject);
begin
if observador = nil then
raise IllegalArgumentException.Create(‘O parâmetro ‘‘observador’’ não pode ser nulo!’);
Self.observador := observador;
end;
function Jogador.segurarTesouro(tesouro : TTesouro) : TTesouro;
begin
levantarExcecaoParametroNulo(tesouro, ‘pocaoDeVida’);
Result := Self.tesouro;
Self.tesouro := tesouro;
end;
end.
[/code]
sobre não usar o contador de referencia. vc pode usar o TInterfacedPersistent como acima.
nos casos q vc precisa de usar a contagem de referencia é só usar interfacedobject tomando um unico cuidado.
sempre usar referencia do tipo interface pq é a q é contada.
no caso do link o erro tava justamente nisso.