<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Nuss... E Agora?!? &#187; Princípio da Substituição de Liskov</title>
	<atom:link href="http://www.nusseagora.blog.br/tag/principio-da-substituicao-de-liskov/feed" rel="self" type="application/rss+xml" />
	<link>http://www.nusseagora.blog.br</link>
	<description></description>
	<lastBuildDate>Fri, 04 Feb 2011 12:56:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.5</generator>
		<item>
		<title>O Princípio da Substituição de Liskov</title>
		<link>http://www.nusseagora.blog.br/principio-da-substituicao-de-liskov</link>
		<comments>http://www.nusseagora.blog.br/principio-da-substituicao-de-liskov#comments</comments>
		<pubDate>Thu, 03 Sep 2009 13:42:34 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Action Script 3.0]]></category>
		<category><![CDATA[Downloads]]></category>
		<category><![CDATA[Padrões de Projeto]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Princípio da Substituição de Liskov]]></category>

		<guid isPermaLink="false">http://nusseagora.blog.br/?p=627</guid>
		<description><![CDATA[Antes de continuarmos pelos padrões de projeto, acho importante ter aqui uma explicação sobre o Princípio da Substituição de Liskov. Ele é comum nas boas práticas de programação orientada a objetos e seus conceitos aparecem muito ao utilizar diversos padrões de projeto, principalmente no uso de Interfaces em padrões como o State (estado), o Strategy (Estratégia) [...]]]></description>
			<content:encoded><![CDATA[<p><span style="float: left"><!--rec6--></span></p>
<p style="margin-left: 70pt; text-align: justify">Antes de continuarmos pelos padrões de projeto, acho importante ter aqui uma explicação sobre o Princípio da Substituição de Liskov. Ele é comum nas boas práticas de programação orientada a objetos e seus conceitos aparecem muito ao utilizar diversos padrões de projeto, principalmente no uso de Interfaces em padrões como o <a href="http://nusseagora.blog.br/marios-maquinas-de-estados-padrao-de-projetos-state-parte-2/" target="_blank">State</a> (estado), o Strategy (Estratégia) ou os diversos tipos de Factories (Fábricas). Apesar de sua popularidade, ainda sim costuma dar um nó na cabeça de quem está começando.</p>
<p><span id="more-627"></span>Historicamente falando, O princípio foi introduzido em 1993 (muito recente, como podem ver) por <a title="Barbara Liskov" href="http://pt.wikipedia.org/wiki/Barbara_Liskov">Barbara Liskov</a> e Jeannette Wing no artigo <em>Family Values: A Behavioral Notion of Subtyping</em>. Segundo ele:</p>
<p><em> </em></p>
<blockquote><p><em>Se q(x) é uma propriedade demonstrável dos objetos x de tipo T. Então q(y) deve ser verdadeiro para objetos y de tipo S onde S é um subtipo de T.</em></p></blockquote>
<p><em> </em></p>
<p><em>“Mas hein?!?”</em> Apesar de parecer complicado, não é. Traduzindo isso para uma linguagem mais simples:</p>
<blockquote><p><em>Se você pode chamar um método q de uma classe TMae, pode também chamar o método q de uma classe TFilha com herança de TMae.</em></p></blockquote>
<p><em> </em></p>
<p><em>“Bom, melhorou bastante. Mas você não pode explicar melhor não, Tiago?”</em> Se uma classe herda de outra classe, cria-se a relação de “é um”. Explicar isso à fundo é material para um outro artigo, mas basta dizer que quando a classe <strong>TFilha</strong> herdou os métodos de <strong>TMae</strong>, ela passou a ser uma <strong>TMae</strong> estendida, melhorada (daí algumas linguagens utilizarem a palavra <strong>extends</strong> para definir herança): ela tem TUDO que uma <strong>TMae</strong> tem, além das coisas que só <strong>TFilha</strong> tem.</p>
<p>Se <strong>TFilha</strong> tem tudo que a <strong>TMae</strong> tem, as chamadas por <strong>TMae</strong> podem receber uma <strong>TFilha</strong> sem o menor problema. Entendamos o código abaixo:</p>
<p>Primeiro criamos uma classe TMae:</p>
<pre class="brush:java">package Classes
{
	public class TMae
	{
		public function TMae()
		{
		}

		public function Voce(): void
		{
			trace ("Eu sou uma TMae");
		}
	}
}</pre>
<p>Como <strong>TMae</strong> precisa de uma filha, vamos criá-la herdando de sua mãe:</p>
<pre class="brush:java">package Classes
{
	import Classes.TMae;

	public class TFilha extends TMae
	{
		public function TFilha(): void
		{
			super(); // Chama o construtor da classe TMae
  		}

		public override function Voce():void
		{
			trace ("Eu sou uma TFilha");
		}

		public function Mae():void
		{
			// chama o método Voce() da classe mãe
			super.Voce();
		}
	}
}</pre>
<p>Vale lembrar que TFilha pode ter seus extras, como fiz com o método Mae(), que exibe a mãe de filha, o método <em>Voce()</em> de <em>super</em>. Para colocar isso tudo para funcionar, precisamos da classe TMain:</p>
<pre class="brush:java">package
{
	import flash.display.MovieClip;
	import Classes.TMae;
	import Classes.TFilha;

	public class TMain extends MovieClip
	{
		public function TMain(): void
		{
			var mae: TMae = new TMae();
			var filha: TFilha = new TFilha();

			trace ("======= MAE =======");
			this.testarLiskov(mae);

			trace ("======= FILHA =======");
			this.testarLiskov(filha);

			trace ("======= MAE DA FILHA =======");
			filha.Mae();

			//trace ("======= MAE DA MAE? =======");
			//mae.Mae();
		}

		public function testarLiskov(obj:TMae)
		{
			obj.Voce();
		}
	}
}</pre>
<p>A saída disso é a seguinte:</p>
<pre>	======= MAE =======
	Eu sou uma TMae
	======= FILHA =======
	Eu sou uma TFilha
	======= MAE DA FILHA =======
	Eu sou uma TMae</pre>
<p>Para terminar, lembrem-se que o Princípio da Substituição de Liskov <strong>não é comutativo</strong>. Ou seja: <strong>podemos trocar a TMae por uma TFilha, mas não uma TFilha por uma TMae</strong>. Se <strong>TFilha</strong> pode possuir mais métodos e atributos  que <strong>TMae, não temos como chamá-los diretamente por TMae. </strong>Para confirmar, basta descomentar a linha <em>mae.Mae()</em> e ver que o compilador não consegue encontrar o método <em>Mae()</em> em TMae (claro, ele é de TFilha!).</p>
<p style="text-align: right;">Saiba mais sobre o <a href="http://pt.wikipedia.org/wiki/Princ%C3%ADpio_da_substitui%C3%A7%C3%A3o_de_Liskov" target="_blank">Princípio na Wikipédia</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nusseagora.blog.br/principio-da-substituicao-de-liskov/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

