Programmation Orientée Objet

De manière superficielle, le terme orienté objet signifie que nous organisons le logiciel comme une collection d'objets dissociés comprenant à la fois une structure de données - attributs - et un comportement - méthodes - dans une même entité.

Une voiture peut avoir une certaine couleur et en même temps possède un comportement qui sera le même pour toutes les autres voitures, comme accélérer. Ce concept est différent de la programmation conventionnelle dans laquelle les structures de données et les fonctionnalités ne sont que faiblement associés.
Liste des travaux pratiques

Circonférence et surface d'un cercle

Vous allez développer une petite application fenêtrée qui permet de retrouver la circonférence et la surface d'un cercle à partir de son rayon. Pour cela, dans un fichier en-tête séparé, indépendamment de la structure de la fenêtre, vous allez construire une classe Cercle qui met en oeuvre ces différentes fonctionalités qui seront exploitées par les composants de Qt qui permettent de gérer l'affichage des valeurs et la saisie du rayon.

Interface Homme Machine du projet et conception de l'application

Vous avez ci-dessus toute l'architecture de l'IHM. Respectez le nom de chacun des objets composants utilisés. Pensez à prévoir un préfixe et un suffixe pour chacun des objets de type QDoubleSpinBox. Enfin, dans le code source relatif à la classe Principal, pensez à mettre en place le slot rayonChange(double).

Diagramme des composants (logiciels)

Dans ce diagramme, vous remarquez la présence d'un fichier supplémentaire cercle.h sans le fichier source cercle.cpp. C'est à l'intérieur de ce fichier en-tête que vous allez déclarer la classe Cercle dont le contenu est décrit dans le diagramme de classes ci-dessous. C'est également à l'intérieur de ce fichier que vous allez définir toutes les méthodes de la classe en version inline. D'après le diagramme, vous remarquez également la relation entre la classe Principal et la classe Cercle . C'est dans la classe Principal que vous allez utiliser un objet de type Cercle qui permettra de réaliser les traitements qui seront visualisés à l'aide de l'IHM.

Diagramme de classes

  1. Dans le fichier cercle.h : Déclarez la classe Cercle et définissez l'ensemble des méthodes inline qui vous sont proposées par le diagramme ci-dessus.
  2. Dans le fichier principal.h déclarer l'attribut cercle ainsi que la méthode de rappel rayonChange().
  3. Dans le fichier principal.cpp définissez le slot rayonChange() de telle sorte que les résultats soient mis à jour en utilisant les compétences l'objet cercle.
cercle.h
#ifndef CERCLE_H
#define CERCLE_H

class Cercle
{
  double rayon = 1.0;
  const double PI = 3.1415926;
public:
  void setRayon(double rayon);
  double perimetre() const;
  double surface() const;
};

inline void Cercle::setRayon(double rayon)  { this->rayon = rayon; }
inline double Cercle::perimetre() const     { return 2*PI*rayon; }
inline double Cercle::surface() const       { return PI*rayon*rayon; }

#endif // CERCLE_H
principal.h
#ifndef PRINCIPAL_H
#define PRINCIPAL_H

#include "ui_principal.h"
#include "cercle.h"

class Principal : public QMainWindow, private Ui::Principal
{
  Q_OBJECT

public:
  explicit Principal(QWidget *parent = 0);
private:
  Cercle cercle;
private slots:
  void rayonChange(double nouveau);
};

#endif // PRINCIPAL_H
principal.cpp
#include "principal.h"

Principal::Principal(QWidget *parent) : QMainWindow(parent)
{
  setupUi(this);
  rayonChange(1.0);
}

void Principal::rayonChange(double nouveau)
{
  cercle.setRayon(nouveau);
  perimetre->setValue(cercle.perimetre());
  surface->setValue(cercle.surface());
}

Trigonométrie avec un triangle rectangle

Vous allez développer maintenant une autre application fenêtrée qui permet d'effectuer un certain nombre de calculs relatifs au triangle rectangle comme, l'hypoténuse, la surface du rectangle, le sinus, le cosinus, la tangente et la valeur de l'angle entre le côté adjacent et l'hypoténuse.

Interface Homme Machine du projet et conception de l'application

Vous avez ci-dessus toute l'architecture de l'IHM. Respectez le nom de chacun des objets composants utilisés. Pensez à prévoir un préfixe et un suffixe pour chacun des objets de type QDoubleSpinBox. Enfin, dans le code source relatif à la classe Principal, pensez à mettre en place les slot changeLargeur(double) et changeHauteur(double).

Diagramme des composants (logiciels)

Dans ce diagramme, vous remarquez la présence d'un fichier supplémentaire triangle.h sans le fichier source triangle.cpp. C'est à l'intérieur de ce fichier en-tête que vous allez déclarer la classe Triangle dont le contenu est décrit dans le diagramme de classes ci-dessous. C'est également à l'intérieur de ce fichier que vous allez définir toutes les méthodes de la classe en version inline. D'après le diagramme, vous remarquez également la relation entre la classe Principal et la classe Triangle . C'est dans la classe Principal que vous allez utiliser un objet de type Triangle qui permettra de réaliser les traitements qui seront visualisés à l'aide de l'IHM.

Diagramme de classes

  1. Dans le fichier triangle.h : Déclarez la classe Triangle et définissez l'ensemble des méthodes inline qui vous sont proposées par le diagramme ci-dessus.
  2. Dans le fichier principal.h déclarer l'attribut triangle ainsi que les méthodes de rappel changeLargeur() et changeHauteur() et enfin la méthode privée calcul().
  3. Dans le fichier principal.cpp définissez les slots changeLargeur() et changeHauteur() afin que l'objet triangle soit mis à jour et lancer ensuite la méthode calcul() qui permet de réafficher les résultats en utilisant les nouvelles valeurs de l'objet triangle.
triangle.h
#ifndef TRIANGLE_H
#define TRIANGLE_H

#include <math.h>

class Triangle
{
  double largeur=1.0, hauteur=1.0;
public:
  void setLargeur(double largeur);
  void setHauteur(double hauteur);
  double hypotenuse() const;
  double surface() const;
  int    angle() const;
  double sinus() const;
  double cosinus() const;
  double tangente() const;
};

inline void Triangle::setLargeur(double largeur)  { this->largeur = largeur; }
inline void Triangle::setHauteur(double hauteur)  { this->hauteur = hauteur; }
inline double Triangle::hypotenuse() const        { return sqrt(largeur*largeur + hauteur*hauteur); }
inline double Triangle::surface() const           { return largeur*hauteur/2.0; }
inline double Triangle::sinus() const             { return hauteur/hypotenuse(); }
inline double Triangle::cosinus() const           { return largeur/hypotenuse(); }
inline double Triangle::tangente() const          { return hauteur/largeur; }
inline int    Triangle::angle() const             { return atan2(hauteur, largeur)*180/M_PI; }

#endif // TRIANGLE_H
principal.h
#ifndef PRINCIPAL_H
#define PRINCIPAL_H

#include "ui_principal.h"
#include "triangle.h"

class Principal : public QMainWindow, private Ui::Principal
{
  Q_OBJECT

public:
  explicit Principal(QWidget *parent = 0);
private:
  Triangle triangle;
private slots:
  void changeLargeur(double nouveau);
  void changeHauteur(double nouveau);
private:
  void calcul();
};

#endif // PRINCIPAL_H
principal.cpp
#include "principal.h"

Principal::Principal(QWidget *parent) : QMainWindow(parent)
{
  setupUi(this);
  calcul();
}

void Principal::changeLargeur(double nouveau)
{
  triangle.setLargeur(nouveau);
  calcul();
}

void Principal::changeHauteur(double nouveau)
{
  triangle.setHauteur(nouveau);
  calcul();
}

void Principal::calcul()
{
  hypotenuse->setValue(triangle.hypotenuse());
  surface->setValue(triangle.surface());
  cosinus->setValue(triangle.cosinus());
  sinus->setValue(triangle.sinus());
  tangente->setValue(triangle.tangente());
  angle->setValue(triangle.angle());
}