<?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>Le nid de dodo &#187; superclasse</title>
	<atom:link href="https://blog.developpez.com/dodo/ptag/superclasse/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/dodo</link>
	<description></description>
	<lastBuildDate>Sat, 19 Oct 2024 00:29:26 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.42</generator>
	<item>
		<title>Le constructeur, au croisement de tous les dangers</title>
		<link>https://blog.developpez.com/dodo/p12675/langage/le-constructeur-au-croisement-de-tous-les-dangers</link>
		<comments>https://blog.developpez.com/dodo/p12675/langage/le-constructeur-au-croisement-de-tous-les-dangers#comments</comments>
		<pubDate>Sun, 20 Jul 2014 09:37:31 +0000</pubDate>
		<dc:creator><![CDATA[bredelet]]></dc:creator>
				<category><![CDATA[Dodo]]></category>
		<category><![CDATA[Langage]]></category>
		<category><![CDATA[Théorie]]></category>
		<category><![CDATA[constructeur]]></category>
		<category><![CDATA[dodo]]></category>
		<category><![CDATA[fragile]]></category>
		<category><![CDATA[objet]]></category>
		<category><![CDATA[superclasse]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/dodo/?p=96</guid>
		<description><![CDATA[Les constructeurs sont, en dodo, là où le langage devient impératif. Le constructeur fait habituellement partie du baggage associé à la programmation orientée objet; cependant, ce n’est pas un composant essentiel de celle-ci. Il est tout à fait envisageable de faire de la programmation objet en se contentant de fonctions &#171;&#160;fabrique&#160;&#187; qui produisent des instances de classe en fonction de paramètres définis. Ce qui distingue un constructeur de ces dernières, c’est que le constructeur agit [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Les constructeurs sont, en dodo, là où le langage devient <em>impératif</em>.</p>
<p>Le <em>constructeur</em> fait habituellement partie du baggage associé à la programmation orientée objet; cependant, ce n’est pas un composant essentiel de celle-ci. Il est tout à fait envisageable de faire de la programmation objet en se contentant de <em>fonctions &laquo;&nbsp;fabrique&nbsp;&raquo;</em> qui produisent des instances de classe en fonction de paramètres définis.</p>
<p>Ce qui distingue un constructeur de ces dernières, c’est que le constructeur agit sur une instance déjà allouée de la classe et peut (ou parfois, doit) déléguer partie de l’initialisation de l’objet à la superclasse.</p>
<p>Cette dernière propriété est la source de bien des soucis pour le programmeur orienté objet.</p>
<p>Prenons un exemple:</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">class A<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; make construireA<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; self.<span style="color: #202020;">Init</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; method Init<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; F<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; method F<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>Dans cet exemple, le constructeur ne fait finalement rien. Mais une sous-classe peut avoir davantage d’attributs:</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">def B <span style="color: #339933;">=</span> new A is Mutable<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #993333;">int</span> x<br />
&nbsp; &nbsp; make construireB<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> x<span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Super<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #666666; font-style: italic;">// invoquer construireA</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; .<span style="color: #202020;">self</span>.<span style="color: #202020;">x</span> <span style="color: #339933;">=</span> x<br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; method <span style="color: #339933;">^</span>F<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">case</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>x <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LancerOgive<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>Dans <em>B</em>, le constructeur de <em>A</em> ne semble plus du tout anodin: puisque <code class="codecolorer text default"><span class="text">x</span></code> n’est pas encore initialisé, il prend la valeur par défaut <strong>0</strong> quand le constructeur de <em>A</em> appelle <em>F()</em>, et la fonction au nom inquiétant <em>LancerOgive()</em> est invoquée!</p>
<p>Même si le développeur prend bien soin que <code class="codecolorer text default"><span class="text">self.x</span></code> ne soit jamais <strong>0</strong> tant qu’il n’y a pas d’attaque en cours contre la sûreté nationale dans les méthodes de <em>B</em>, il est trop tard. Et le pire est qu’il n’a pas forcément de contrôle sur la classe <em>A</em>; l’appel à la méthode <em>F()</em> pourrait avoir été ajouté après que tous les tests du programme soient passés. C’est un problème général des langages orientés objet, dit <em>&laquo;&nbsp;la superclasse fragile&nbsp;&raquo;</em>.</p>
<p>Pour résoudre cela on pourrait interdire au constructeur de <em>B</em> d’appeler le constructeur de <em>A</em> sur <code class="codecolorer text default"><span class="text">self</span></code>, mais il suffirait de remplacer cet appel avec celui de <em>self.Init()</em> pour retomber sur le même problème. En fin de compte, ce qui est important est que la variable <code class="codecolorer text default"><span class="text">x</span></code> soit initialisée avant tout appel aux méthodes de <em>A</em>.</p>
<p>A noter qu’en dodo, il n’est pas toujours possible de provoquer ce problème. Les conditions qui le permettent sont:</p>
<ul>
<li>Le type <em>A</em> est polymorphique (venant de <code class="codecolorer text default"><span class="text">class</span></code>)</li>
<p>Si ce n&rsquo;était pas le cas, la fonction <em>F()</em> appelée dans <em>Init()</em> serait celle de <em>A</em>, puisque <em>Init()</em> n’aurait pas moyen de savoir que <code class="codecolorer text default"><span class="text">self</span></code> est en réalité de type <em>B</em> et non <em>A</em>. Alors <em>LancerOgive()</em> ne serait pas invoquée.</p>
<li>Le type B réutilise le prototype de A (<code class="codecolorer text default"><span class="text">def B</span></code>)</li>
<p>Autrement, <em>B</em> ne pourrait pas invoquer la moindre méthode ou fonction de <em>A</em> sur <code class="codecolorer text default"><span class="text">self</span></code>, puisque la structure des instances de <em>B</em> et de <em>A</em> n’ont potentiellement rien en commun. Cela est permis en dodo, et dans ce cas <em>A</em> est utilisé comme une interface que <em>B</em> implémente à sa façon.</p>
<li>Le constructeur (ou une méthode) de <em>A</em> est invoqué avant que tous les attributs de <em>B</em> ne soient correctement initialisés.</li>
<p>Cela implique que ces attributs n’ont pas une valeur par défaut bien choisie.
</ul>
<p>J’ai mentionné le fait que dodo est un langage impératif par le biais des ses constructeurs. De fait, à l’intérieur d’un constructeur il est permis d’appeler d’autres constructeurs, appeler des méthodes avec effets de bord et aussi affecter de nouvelles valeurs aux attributs de l’objet, même si la classe n’est pas <em>Mutable</em> ou <em>Editable</em> (qui est une extension de Mutable).</p>
<p>Mais appeler des méthodes sur <code class="codecolorer text default"><span class="text">self</span></code>, alors que les attributs de <code class="codecolorer text default"><span class="text">self</span></code> peuvent encore changer, ne semble pas une bonne idée quand l’objet est sensé être constant. Les méthodes en question pourraient être déroutées quand les attributs de l’objet n’ont plus la valeur qu’ils prétendaient avoir. Pour cette raison dodo devrait imposer cette règle: affecter une nouvelle valeur aux attributs de l’objet n’est pas permis après que <code class="codecolorer text default"><span class="text">self</span></code> a été passé à une méthode ou un autre constructeur dans le constructeur de la classe. Cela s’applique uniquement aux objets qui ne sont pas <em>Mutable</em>.</p>
<p>Pour que le danger de la superclasse fragile affecte une classe dodo, il faut donc que la superclasse soit <em>Polymorphic</em>, qu’elle soit modifiée sans préavis, que la classe affectée soit <em>Mutable</em>, réutilise le prototype de la superclasse, n’ait pas de valeur par défaut bien choisie pour ses attributs et fasse appel à des méthodes ou constructeurs de la superclasse avant d&rsquo;être complètement initialisée.</p>
<p>Il n’est pas très difficile de réunir tous ces ingrédients mais il est encore plus facile d&rsquo;éviter le danger.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
