{"id":696,"date":"2017-10-22T10:34:40","date_gmt":"2017-10-22T09:34:40","guid":{"rendered":"http:\/\/chezdom.net\/etu\/?p=696"},"modified":"2017-10-22T11:50:53","modified_gmt":"2017-10-22T10:50:53","slug":"correction-tp1-java-exercice-2","status":"publish","type":"post","link":"https:\/\/chezdom.net\/etu\/2017\/10\/22\/correction-tp1-java-exercice-2\/","title":{"rendered":"Correction TP1 JAVA &#8211; Exercice 2"},"content":{"rendered":"<p>Correction de l&rsquo;exercice 2 du TP : <a href=\"http:\/\/chezdom.net\/etu\/java-miashs-12017-tp-1\/\">\u00c9nonc\u00e9 du TP1<\/a><br \/>\nToutes le code ci-dessous est impl\u00e9ment\u00e9 dans le fichier <code>Times.java<\/code>, et dans la classe <code>Times<\/code>.<\/p>\n<h2>2.1 Constructeurs<\/h2>\n<ol>\n<li>Pour les secondes, on va mettre 0.\n<pre class=\"brush: java\">    public Times(int hours, int mins) {\r\n        this(hours, mins, 0);\r\n    }\r\n<\/pre>\n<p>L&rsquo;avantage d&rsquo;utiliser l&rsquo;autre constructeur, comme c&rsquo;\u00e9tait d\u00e9j\u00e0 fait pour le constructeur de copie, est qu&rsquo;on n&rsquo;a pas \u00e0 r\u00e9\u00e9crire le code (\u00e9videmment dans cet exemple c&rsquo;est tr\u00e8s court, mais des constructeurs de classes plus complexes peuvent \u00eatre tr\u00e8s longs). De plus si on doit modifier, en cours de d\u00e9veloppement certains des arguments, on aura pas \u00e0 reporter les m\u00eames modifications plusieurs fois, au risque d&rsquo;en oublier. En r\u00e8gle g\u00e9n\u00e9rale il faut au maximum utiliser le m\u00eame code pour les m\u00eames t\u00e2ches.<\/li>\n<li>Dans le cas du constructeur sans argument, il faudrait \u00e9crire\n<pre class=\"brush: java\">    public Times() {\r\n        java.time.LocalDateTime now = java.time.LocalDateTime.now();\r\n        this(now.getHour(), now.getMinute(), now.getSecond());\r\n    }\r\n<\/pre>\n<p>Or ce n&rsquo;est pas possible car l&rsquo;appel \u00e0 un autre constructeur doit \u00eatre la premi\u00e8re instruction. La compilation donne :<\/p>\n<pre class=\"brush: shell\">tp1$ javac Times.java \r\nTimes.java:18: error: call to this must be first statement in constructor\r\n        this(now.getHour(), now.getMinute(), now.getSecond());\r\n            ^\r\n1 error\r\n<\/pre>\n<p><strong>Il faut toujours lire soigneusement les messages d&rsquo;erreur si on veut avoir une chance de corriger.<\/strong><\/p>\n<p>On peut contourner ce probl\u00e8me en cr\u00e9ant une fonction (qu&rsquo;on appellera par exemple <code>initTimes<\/code>, qui sera appel\u00e9e par les constructeurs.<\/p>\n<pre class=\"brush: java\">    public void initTimes(int hours, int mins, int secs) {\r\n        this.hours = hours;\r\n        this.mins = mins;\r\n        this.secs = secs;\r\n    }\r\n\r\n    public Times() {\r\n        java.time.LocalDateTime now = java.time.LocalDateTime.now();\r\n        initTimes(now.getHour(), now.getMinute(), now.getSecond());\r\n    }\r\n\r\n    public Times(int hours, int mins, int secs) {\r\n        initTimes(hours, mins, secs);\r\n    }\r\n\r\n    public Times(int hours, int mins) {\r\n        initTimes(hours, mins, 0);\r\n    }\r\n\r\n    public Times(Times source) {\r\n        initTimes(source.hours, source.mins, source.secs);\r\n    }\r\n<\/pre>\n<\/li>\n<\/ol>\n<h2>2.2 M\u00e9thodes<\/h2>\n<ol>\n<li>On va commencer par cr\u00e9er plusieurs objets de type <code>Times<\/code> en utilisant les diff\u00e9rents constructeurs, puis on les affichera et on appellera les diff\u00e9rentes m\u00e9thodes \u00e0 tester, en affichant \u00e0 la fois les objets qui auront \u00e9t\u00e9 modifi\u00e9s.<\/li>\n<li>\n<pre class=\"brush: java\">    public static void main(String[] args) {\r\n        Times now=new Times();\r\n        System.out.println(&quot;it is &quot;+now);\r\n        Times other=new Times(now);\r\n        System.out.println(&quot;other : &quot;+ other);\r\n\r\n        if (now.equals(other))\r\n            System.out.println(&quot;les 2 objets contiennent la m\u00eame chose&quot;);\r\n        else\r\n            System.out.println(&quot;les 2 objets contiennent des valeurs diff\u00e9rentes&quot;);\r\n\r\n        other.addMinutes(1);\r\n        System.out.println(&quot;valeur de now: &quot;+now);\r\n        System.out.println(&quot;valeur de other: &quot;+other);\r\n        if (now.equals(other))\r\n            System.out.println(&quot;les 2 objets contiennent la m\u00eame chose&quot;);\r\n        else\r\n            System.out.println(&quot;les 2 objets contiennent des valeurs diff\u00e9rentes&quot;);\r\n}\r\n<\/pre>\n<p>Ex\u00e9cution<\/p>\n<pre class=\"brush: shell\">tp1$ java Times\r\nit is 11:54:26\r\nother : 11:54:26\r\nles 2 objets contiennent la m\u00eame chose\r\nvaleur de now: 11:54:26\r\nvaleur de other: 11:55:26\r\nles 2 objets contiennent des valeurs diff\u00e9rentes\r\n<\/pre>\n<\/li>\n<li>Test de <code>addMinutes<\/code>\n<pre class=\"brush: java\">    public static void main(String[] args) {\r\n      \/\/ ...\r\n        other.addMinutes(90);\r\n        System.out.println(&quot;other +90 min : &quot;+ other);\r\n      \/\/ ...\r\n<\/pre>\n<p>Ex\u00e9cution<\/p>\n<pre class=\"brush: shell\">tp1$ java Times\r\nit is 12:1:58\r\nother : 12:1:58\r\nother +90 min : 12:91:58\r\n<\/pre>\n<p>On a pas pris en compte le fait que le nombre de minute ne peut d\u00e9passer 59 !<\/li>\n<li>Un autre probl\u00e8me, que l&rsquo;on peut aussi voir sur l&rsquo;ex\u00e9cution pr\u00e9c\u00e9dente, est que l&rsquo;affichage des minutes (et des secondes) est mauvais dans le cas de nombres inf\u00e9rieurs \u00e0 10.<\/li>\n<li>Correction de ces 2 m\u00e9thodes\n<pre class=\"brush: java\">    public void addMinutes(int n) {\r\n        this.mins+=n;\r\n        if (this.mins&gt;=60) {\r\n            this.hours+=(this.mins\/60);\r\n            this.mins=this.mins%60;\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public String toString() {\r\n        String offsetM=mins&lt;10?&quot;0&quot;:&quot;&quot;;\r\n        String offsetS=secs&lt;10?&quot;0&quot;:&quot;&quot;;\r\n        return hours+&quot;:&quot;+offsetM+mins+&quot;:&quot;+offsetS+secs;\r\n\r\n    }\r\n<\/pre>\n<p>Ex\u00e9cution<\/p>\n<pre class=\"brush: shell\">tp1$ java Times\r\nit is 12:02:00\r\nother : 12:02:00\r\nother +90 min : 13:32:00\r\n<\/pre>\n<\/li>\n<li>Cette ligne est parfaitement correcte pour JAVA. Cela va cr\u00e9er une heure qui,<br \/>\nelle, n&rsquo;aura aucun sens.<\/li>\n<li>Pour \u00e9viter cela il faut faire des v\u00e9rifications au moment de la cr\u00e9ation d&rsquo;une heure. Il y a plusieurs strat\u00e9gies.\n<ul>\n<li>La premi\u00e8re consiste \u00e0 tenter de corriger le probl\u00e8me (mais ce n&rsquo;est pas toujours possible) &#8211; par exemple ici on pourrait calculer que 99 secondes, c&rsquo;est 1 min 39, et ajouter cette minute au nombre de minutes, puis voir que 66 minutes c&rsquo;est 1h et 6 minutes pour aboutir \u00e0 2:06:39. Si on d\u00e9passe 24h l\u00e0 on aura un probl\u00e8me (qu&rsquo;on ne peut pas vraiment r\u00e9soudre dans ajouter la date &#8211; c&rsquo;est pourquoi toutes les classes permettant de manipuler des heures sont en fait des classes Date-Heure, par exemple la classe que nous avons utilis\u00e9 pour le constructeur sans argument <code>LocalDateTime<\/code>.<\/li>\n<li>La seconde consiste \u00e0 envoyer un message d&rsquo;erreur, et arr\u00eater le programme.<\/li>\n<li>Enfin les langages modernes (dont Java) proposent un m\u00e9canisme appel\u00e9 \u00ab\u00a0Gestion d&rsquo;exceptions\u00a0\u00bb, qui permet de r\u00e9cup\u00e9rer ce type d&rsquo;erreur sans arr\u00eater le programme (mais nous le verrons plus tard).<\/li>\n<\/li>\n<\/ol>\n<h2>2.3 De nouvelles m\u00e9thodes<\/h2>\n<ol>\n<li>\n<pre class=\"brush: java\">    public boolean isBefore(Times other) {\r\n        return (this.hours&lt;other.hours)\r\n                || (this.mins &lt; other.mins)\r\n                || (this.secs &lt; other.secs);\r\n    }\r\n\r\n    public boolean isAfter(Times other) {\r\n        return !isBefore(other)&amp;&amp;!equals(other);\r\n    }\r\n<\/pre>\n<\/li>\n<li>\n<pre class=\"brush: java\">    public void addSecondes(int n) {\r\n        this.secs+=n;\r\n        if (this.secs&gt;=60) {\r\n            this.addMinutes(this.secs\/60);\r\n            this.secs=this.secs%60;\r\n        }\r\n    }\r\n<\/pre>\n<\/li>\n<li>\n<ul>\n<li>Calculer la dur\u00e9e entre 2 heures.<\/li>\n<li>Afficher \u00e0 diff\u00e9rents formats (3.12am, ou 12h 8&prime; et 14\u00a0\u00bb)<\/li>\n<li>Gestion des fuseaux horaires (mais cela n&rsquo;a de sens que si la date est incluse.<\/li>\n<\/ul>\n<\/ol>\n<h2>2.4 Une alarme<\/h2>\n<ol>\n<li>\n<pre class=\"brush: java\">\r\n    public void minuteur(int nbSecs) {\r\n        Times alarm=new Times(this);\r\n        alarm.addSecondes(nbSecs);\r\n\r\n        while (!alarm.equals(new Times())) {\r\n            \/\/sleep(500);\r\n        }\r\n        System.out.println(&quot;Done! &quot;+(new Times()));\r\n    }\r\n<\/pre>\n<\/li>\n<li>Attention cela va bloquer le syst\u00e8me en attendant l&rsquo;ex\u00e9cution. Il faudrait mettre le processus en attente (<code>sleep<\/code>), nous verrons cela plus tard avec la notion de <code>Thread<\/code>.\n<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>Correction de l&rsquo;exercice 2 du TP : \u00c9nonc\u00e9 du TP1 Toutes le code ci-dessous est impl\u00e9ment\u00e9 dans le fichier Times.java, et dans la classe Times. 2.1 Constructeurs Pour les secondes, on va mettre 0. public Times(int hours, int mins) {<span class=\"ellipsis\">&hellip;<\/span> <span class=\"read-more\"><a href=\"https:\/\/chezdom.net\/etu\/2017\/10\/22\/correction-tp1-java-exercice-2\/\">Lire la suite &#8250;<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-696","post","type-post","status-publish","format-standard","hentry","category-non-classe"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9qu1A-be","_links":{"self":[{"href":"https:\/\/chezdom.net\/etu\/wp-json\/wp\/v2\/posts\/696","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/chezdom.net\/etu\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/chezdom.net\/etu\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/chezdom.net\/etu\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/chezdom.net\/etu\/wp-json\/wp\/v2\/comments?post=696"}],"version-history":[{"count":13,"href":"https:\/\/chezdom.net\/etu\/wp-json\/wp\/v2\/posts\/696\/revisions"}],"predecessor-version":[{"id":710,"href":"https:\/\/chezdom.net\/etu\/wp-json\/wp\/v2\/posts\/696\/revisions\/710"}],"wp:attachment":[{"href":"https:\/\/chezdom.net\/etu\/wp-json\/wp\/v2\/media?parent=696"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/chezdom.net\/etu\/wp-json\/wp\/v2\/categories?post=696"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/chezdom.net\/etu\/wp-json\/wp\/v2\/tags?post=696"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}