import [Link].
ArrayList;
import [Link];
// 1. Abstraction de base - SRP : juste les données communes
abstract class Personne {
protected String matricule;
protected String nom;
protected double salaireBase;
public Personne(String matricule, String nom, double salaireBase) {
[Link] = matricule;
[Link] = nom;
[Link] = salaireBase;
public String getMatricule() { return matricule; }
public String getNom() { return nom; }
public double getSalaireBase() { return salaireBase; }
// Méthode abstraite : chaque type calcule son salaire différemment
public abstract double calculerSalaire();
// 2. Interface petite et ciblée - ISP
interface Travaillable {
void travailler();
String getPoste();
// 3. Classe Agent - OCP : extensible sans modifier Personne
class Agent extends Personne implements Travaillable {
private String service;
public Agent(String matricule, String nom, double salaireBase, String service) {
super(matricule, nom, salaireBase);
[Link] = service;
@Override
public double calculerSalaire() {
return salaireBase; // Pas de prime pour un agent simple
@Override
public void travailler() {
[Link](nom + " travaille au service " + service);
@Override
public String getPoste() {
return "Agent - " + service;
// 4. Classe Infirmier - OCP : nouveau type sans toucher Agent
class Infirmier extends Personne implements Travaillable {
private int heuresNuit;
public Infirmier(String matricule, String nom, double salaireBase, int heuresNuit) {
super(matricule, nom, salaireBase);
[Link] = heuresNuit;
@Override
public double calculerSalaire() {
double primeNuit = heuresNuit * 1500; // 1500 FC par heure de nuit
return salaireBase + primeNuit;
@Override
public void travailler() {
[Link](nom + " soigne les patients, heures de nuit: " + heuresNuit);
@Override
public String getPoste() {
return "Infirmier";
// 5. Service séparé pour l'affichage - SRP
class RapportService {
public void afficherFiche(Personne p) {
[Link]("-----------------------------");
[Link]("Matricule: " + [Link]());
[Link]("Nom: " + [Link]());
[Link]("Salaire: " + [Link]() + " FC");
if (p instanceof Travaillable) {
Travaillable t = (Travaillable) p;
[Link]("Poste: " + [Link]());
[Link]();
// 6. Service qui dépend d'une abstraction - DIP
class PersonneService {
private List<Personne> personnes = new ArrayList<>();
public void ajouter(Personne p) {
[Link](p);
public void afficherTout(RapportService rapport) {
for (Personne p : personnes) {
[Link](p);
// Exemple de méthode qui marche pour tout type de Personne
public double masseSalariale() {
return [Link]()
.mapToDouble(Personne::calculerSalaire)
.sum();
// 7. Main
public class Main {
public static void main(String[] args) {
PersonneService service = new PersonneService();
RapportService rapport = new RapportService();
[Link](new Agent("AGT001", "Jean Mukendi", 250000, "Vente"));
[Link](new Infirmier("INF002", "Sarah Lumumba", 300000, 10));
[Link](new Infirmier("INF003", "Paul Kabila", 280000, 5));
[Link](rapport);
[Link]("-----------------------------");
[Link]("Masse salariale totale: " + [Link]() + " FC");