[JAVA] Qu'est-ce que l'orientation objet après tout ou juste une chose à surveiller dans la programmation

introduction

Si vous étudiez la programmation, vous avez probablement déjà entendu le terme orienté objet. Cependant, cette orientée objet, qui existe depuis longtemps et qui est encore utilisée par de nombreuses personnes, je ne sais pas ce que cela signifie. En regardant une certaine page, il dit qu'elle contient des éléments d '«encapsulation», d' «héritage» et de «polymorphisme». Mais les partisans orientés objet disent la messagerie. [Wikipédia](https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83 % 88% E6% 8C% 87% E5% 90% 91% E3% 83% 97% E3% 83% AD% E3% 82% B0% E3% 83% A9% E3% 83% 9F% E3% 83% B3 Même si vous regardez% E3% 82% B0), il n'est pas clair que l'arrière-plan continue pendant longtemps et il existe de nombreux types.

Après tout, je pense que beaucoup de gens ont une vague compréhension du fait que les variables et méthodes suivantes sont solidifiées (pour ceux qui sont complètement nouveaux, Supplément) Veuillez lire en premier).

public class SandBox {
    int hoge = 10;
    int fuga = 20;
    
    int foo(){
        return hoge;
    }
    int bar(){
        return fuga;
    }
}

Cependant, ce que j'ai trouvé après avoir continué la programmation pour les loisirs et les affaires, c'est qu'elle était orientée objet, ou que le discours de type «programmation devrait être XX» existe pour ** un seul but **. Si vous savez cela, des techniques de programmation telles que l'orientation objet et «donnons un nom de variable descriptif» seront introduites immédiatement.

Code lisible

Quand j'ai commencé à programmer comme passe-temps, je ne comprenais pas pourquoi je devais le rendre orienté objet. J'ai aussi compris les notes telles que «Donnons un nom de variable facile à comprendre», mais je ne pensais pas que c'était important. En fait, vous n'en avez pas besoin si elles sont courtes et vos propres programmes. Par exemple, si vous souhaitez renommer des fichiers dans un dossier à la fois (ajouter [lecture] au début), ce code est suffisant.

File a = new File("C:\\Users\\admin\\Documents\\ss");
for(File f : a.listFiles()){
    File b = new File(a, "[Déjà lu]"+f.getName());
    f.renameTo(b);
}

Vous n'avez pas à vous soucier de créer un objet. Il n'est pas nécessaire de donner un nom de variable descriptif. C'est juste un tracas à faire parce que vous ne devez l'utiliser qu'une seule fois et vous connaître.

Ensuite, la raison pour laquelle l'orientation objet et la façon de nommer les variables sont absurdement débattues est qu'elle est destinée aux programmes développés par ** multijoueur à long terme **. Les programmes développés par les entreprises sont créés par un grand nombre de personnes dans une grande entreprise et peuvent être modifiés au fil des ans. C'est pourquoi le code doit être faiblement couplé (voir ci-dessous) afin que d'autres personnes puissent lire et comprendre le code afin que les changements n'affectent pas l'inattendu. Si vous pensez "Je le fais moi-même comme passe-temps, ça n'a pas d'importance", c'est une erreur, et après six mois, j'oublierai la signification du code que j'ai écrit dans le passé, donc j'ai besoin de l'écrire d'une manière facile à comprendre et faiblement couplée. il y a.

En bref, les techniques de programmation telles que l'orientation objet et «donner des noms de variables faciles à comprendre» sont destinées à ** «écrire du code facile à lire et à écrire pour les autres (y compris vous-même dans le futur)» **.

Alors, qu'est-ce que l'orientation objet?

Pour expliquer à ma manière, qu'est-ce qui est orienté objet? ** Créer un groupe (classe) de données et de fonctions tout en observant des règles telles que l'encapsulation afin «d'écrire du code facile à lire et à écrire pour les autres (y compris vous-même dans le futur)». C'est **. Je ne pense pas que ce soit tout, alors jetons un coup d'œil à la classe ArrayList de Java à titre d'exemple.

List<String> list = new ArrayList<String>();
list.add("C");
list.add("A");
System.out.println(list.get(0));//C

Même si vous ne connaissez pas Java (si vous comprenez l'anglais), vous pouvez lire ce code et vous comprendrez que "j'ai ajouté" C "et" A "à la liste pour obtenir le 0ème élément." Il est important de savoir ce que signifie le code sans regarder le contenu de la classe comme ceci **, et c'est pourquoi tout ce que je vais expliquer ci-dessous. Parce qu'un programme créé par une grande entreprise peut avoir des millions de lignes dans certains cas, il est donc impossible de saisir tout le code (et bien sûr, il est souhaitable que même un petit programme ait moins de code à saisir). )est.

Encapsulation

La fonction orientée objet la plus importante est l'encapsulation. Cela signifie "visualiser uniquement les pièces dont l'utilisateur a besoin et masquer le reste". En termes de langage de programmation, il s'agit de définir ** public ** et ** privé ** de manière appropriée. Par exemple, la classe ArrayList a en fait des méthodes telles que ensureCapacityInternal () et grow () à l'intérieur et effectue un traitement compliqué, mais comme elle n'est pas liée au côté qui utilise la liste, elle est privée (privée) et ajoute ( Seules les méthodes utilisées par les utilisateurs telles que) et get () sont publiques. Cela fait d'ArrayList une classe sûre qui est facile à utiliser sans connaître l'intérieur.

Pour le dire plus simplement, par exemple, une calculatrice. Savez-vous à quoi ressemblent les circuits électroniques à l'intérieur de la calculatrice? La plupart des gens ne le savent pas. Mais n'importe qui peut utiliser la calculatrice. En effet, le circuit électronique interne est privé et les boutons et l'écran d'affichage sont publics. Que faire si la calculatrice n'est pas couverte par un boîtier et que les circuits électroniques sont exposés? Si vous êtes très familier avec les circuits électroniques, vous pourrez peut-être le modifier pour en faire votre propre calculatrice spéciale. Cependant, il est incompréhensible pour la plupart des gens, et c'est Sekiyama qui peut causer des problèmes en le touchant accidentellement. Par conséquent, seule la partie qui accepte les opérations externes est rendue publique (publique) et les parties qui ne doivent pas être touchées, comme les circuits électroniques, sont rendues privées (privées). Il s'agit de ** l'encapsulation **. Si vous osez écrire la calculatrice comme un programme, elle ressemblera à ceci.

public class Calculator{
    /**Le bouton "1" est public*/
    public void button1(){
        //En traitement
    }
    /**Le bouton «2» est public*/
    public void button2(){
        //En traitement
    }
    
    ...//Suite ci-dessous
    
    /**Le traitement des calculs internes est privé (privé)*/
    private double calculate(){
        //En traitement
    }
    
    /**L'affichage des résultats est public*/
    public double showResult(){
        //En traitement
    }
}

En pensant ainsi, nous pouvons voir que "l'encapsulation" est universellement présente dans la vie quotidienne. Vous pouvez faire fonctionner le téléviseur sans savoir quel type de signal la télécommande du téléviseur envoie. Vous pouvez conduire une voiture sans connaître la conception du moteur. Même si vous ne connaissez pas les détails de l'ajustement de fin d'année, vous pouvez obtenir l'ajustement de fin d'année en soumettant les documents au service comptable. De cette façon, vous pouvez vivre dans une société compliquée en créant une boîte noire dans laquelle "vous pouvez savoir quoi faire et quel type de résultat sera retourné sans connaître l'intérieur", et les programmes à grande échelle peuvent être facilement compris Sera. Au début, j'ai mentionné que les défenseurs orientés objet disaient «messagerie», mais que les étrangers envoient simplement des «messages» et reçoivent les «messages» renvoyés ** sans connaître l'intérieur ** Il est important de pouvoir programmer.

Serré et faiblement couplé

La connexion forte entre chaque élément est la connexion étroite, et la connexion faible est la connexion lâche. En général, il est préférable de regrouper les éléments étroitement couplés en classes et de les relier de manière lâche. Par exemple, que faire si la classe de calculatrice avait un code pour le calcul de la date? Certaines personnes peuvent penser: "Il vaut mieux avoir une classe qui peut tout faire!", Mais le calcul de la date est assez différent du calcul numérique normal, comme le calcul en divisant la date et en considérant l'année possible. Je vais. Par conséquent, s'il y a un code pour le calcul de la date dans la classe de calculatrice, des méthodes et des variables qui ne sont pas liées les unes aux autres apparaîtront lors de l'édition de l'intérieur de la classe, ce qui sera déroutant. La même chose s'applique à l'utilisateur. Il est préférable de le diviser en une classe de calculatrice et une classe de calcul de date. Et rendre les classes faiblement couplées. Par exemple, si l'état de la classe de calculatrice affecte le comportement de la classe de calcul de date, il peut affecter la classe de calcul de date même si vous avez simplement l'intention de corriger la classe de calculatrice et un bogue inattendu peut apparaître. .. Si vous voulez vraiment changer le comportement de la classe de calcul de date en fonction de l'état de la classe de calculatrice, créez une méthode pour obtenir les paramètres nécessaires de la classe de calculatrice, et créez une méthode pour la recevoir dans la classe de calcul de date pour "visualiser" la coopération.

Polymorphisme (polymorphisme)

Le polymorphisme est que la surface extérieure est la même et le traitement interne peut être modifié de diverses manières. Par exemple, considérons une télécommande de téléviseur. Diverses sociétés telles que Sharp et Panasonic fabriquent des téléviseurs, et la télécommande a également différents circuits électroniques internes, mais elle a le même bouton de commutation de canal et le bouton d'augmentation / diminution du volume, et le fonctionnement est le même. De cette façon, le ** polymorphisme ** a le même aspect externe de «quel type de fonction il a» même si l'implémentation interne est différente. Si vous écrivez la télécommande comme un programme, l '[interface] suivante (https://qiita.com/lamrongol/items/74f62fcbea9cf7e96c4d#%E3%82%A4%E3%83%B3%E3%82% BF% E3% 83% BC% E3% 83% 95% E3% 82% A7% E3% 83% BC% E3% 82% interface B9).

public interface RemoteController{
    public void channel1();
    public void channel2();
    ...//Suite ci-dessous
    public void volumeUp();
    public void volumeDown();
    ...//Suite ci-dessous
}

De cette manière, le rédacteur se verra dire: «Vous pouvez modifier l'implémentation interne, mais promettez d'avoir une telle fonction», et l'utilisateur peut l'utiliser comme télécommande quel que soit le fabricant. Concrètement, par exemple, la classe ArrayList et la classe HashSet de Java ont des éléments assez différents, mais héritent toutes deux de l'interface Collection, donc la méthode ** iterator () est utilisée quelle que soit l'implémentation interne. Vous pouvez voir que vous pouvez mettre les éléments en ordre avec.

Au fait, si vous effectuez une orientation objet, vous pouvez penser "Je comprends l'héritage d'interface, mais l'héritage de classe?", Mais l'héritage de classe se comporte de manière inattendue sans connaître les détails de la classe parente. Si la hiérarchie est profonde, les variables sont dispersées dans plusieurs couches et il devient difficile de les suivre, et les variables du même nom sont dupliquées et confondues, il vaut donc mieux ne pas l'utiliser beaucoup. En fait, les créateurs Java disent aussi que les extensions de classe doivent être évitées autant que possible ).

Édition pratique

Maintenant, faisons une programmation orientée objet simple basée sur ce qui précède. Le langage est Java, mais je vais l'écrire pour que même ceux qui ne connaissent pas Java puissent le comprendre. Ce que nous faisons est un programme qui calcule la "période". Par exemple, si vous travaillez «2 mois 18 jours» puis «1 mois 4 jours», vous obtiendrez un total de «3 mois 22 jours». Cependant, 30 jours sont convertis en 1 mois. En d'autres termes, si vous travaillez «1 mois 24 jours» et «3 mois 15 jours», le total est «4 mois 39 jours», mais 30 jours est converti en 1 mois, soustrayez donc 30 du nombre de jours et ajoutez 1 au mois. , "5 mois 9 jours" est affiché.

Si vous écrivez un programme sans orientation objet, ce sera comme suit.

int monthNum = 0;
int dayNum = 0;

//Travaillez 24 jours sur 24
monthNum = monthNum + 1;
dayNum = dayNum + 24;
////Convertir 30 jours en 1 mois
monthNum = monthNum + dayNum/30;
dayNum = dayNum%30;

//Travail 3 mois 15 jours
monthNum = monthNum + 3;
dayNum = dayNum + 15;
////Convertir 30 jours en 1 mois
monthNum = monthNum + dayNum/30;
dayNum = dayNum%30;

System.out.println((monthNum/12)+"Année"+(monthNum%12)+"mois"+dayNum+"journée");//0Année5mois9journée          

Vous pouvez toujours calculer, mais le code est encombré et vous pouvez obtenir des bogues avec copypemis. Utilisons donc la classe Duration (qui signifie «durée») et créons le code suivant.

Duration durationSum = new Duration(0, 0);

//Travaillez 24 jours sur 24
Duration duration1 = new Duration(1, 24);
durationSum.add(duration1);

//Travail 3 mois 15 jours
Duration duration2 = new Duration(3, 15);
durationSum.add(duration2);

//Automatiquement toString()Est appelé
System.out.println(durationSum);//0 ans 5 mois 9 jours

Et à propos de ça. Je pense que c'est un code soigné que vous pouvez comprendre simplement en lisant (si vous comprenez l'anglais). La classe Duration elle-même ressemble à ceci:

Duration.java


/**Classe "Période". JOURNÉE_OF_Les jours MONTH sont automatiquement convertis en 1 mois*/
public class Duration {
  /**Nombre de jours à considérer comme un mois*/
  public static final int DAY_OF_MONTH = 30;  
  
  //Rendez-le privé afin que les utilisateurs ne puissent pas le modifier sans autorisation
  private int monthNum;//Nombre de mois
  private int dayNum;//Journées
  
  /**monthNum mois jourNum jour*/
  public Duration(int monthNum, int dayNum){
	//DAY_OF_MONTH jour est converti en 1 mois
	this.monthNum = monthNum + dayNum/DAY_OF_MONTH;
	this.dayNum = dayNum % DAY_OF_MONTH;
  }

  public void add(Duration duration){
	this.monthNum = this.monthNum + duration.getMonthNum();
	this.dayNum = this.dayNum + duration.getDayNum();

	//DAY_OF_MONTH jour est converti en 1 mois
	this.monthNum = this.monthNum + this.dayNum/DAY_OF_MONTH;
	this.dayNum = this.dayNum % DAY_OF_MONTH;
  }

  //Rendez-le public afin que les utilisateurs ne puissent pas le définir mais puissent l'obtenir
  public int getMonthNum(){
	return monthNum;
  }
  public int getDayNum(){
	return dayNum;
  }
  
  @Override
  public String toString(){
	  return (monthNum/12)+"Année"+(monthNum%12)+"mois"+dayNum+"journée";
  }
}

Je l'ai écrit dans le code, mais j'ajouterai des explications. Tout d'abord, comme c'est une classe qui représente la période, elle contient les champs monthNum, dayNum pour contenir les mois et les jours, mais dans le constructeur et la méthode ʻadd () , même si dayNumdépasse 30, il est maintenu. Il est contrôlé pour convertir automatiquement en un mois. Par conséquent, nous le rendons privé afin que les utilisateurs ne rompent pas ce contrôle et mettent plus de 30 nombres dansdayNumsans autorisation. Par contre, les méthodesgetMonthNum ()etgetDayNum ()sont rendues publiques (** encapsulation **) car l'acquisition elle-même peut être faite librement. Ensuite, puisque "le nombre de jours considéré comme un mois" est fixé à 30 jours quelle que soit la période,DAY_OF_MONTHest [final](https://qiita.com/lamrongol/items/74f62fcbea9cf7e96c4d#final%E4%BF % AE% E9% A3% BE% E5% AD% 90) dans [statique](https://qiita.com/lamrongol/items/74f62fcbea9cf7e96c4d#static%E4%BF%AE%E9%A3% BE% E5% AD% 90). Et je veux que l'utilisateur sache combien de jours sont convertis en un mois, donc je le rends public. Enfin, il implémente la méthodetoString (). En Java, toutes les classes héritent de la classe Object, et toString ()est la méthode dont elle dispose. En implémentant cela, même la classe que vous avez créée sera affichée en ** mode débogage ** ouSystem.out.println (obj);afin qu'elle soit facile à voir pour les humains. La méthodetoString ()` est une sorte de ** polymorphisme ** car l'implémentation est différente selon la classe car elle est courante et comment l'afficher.

finalement

Comme je l'ai écrit au début, l'important en programmation est ** "d'écrire du code facile à lire et à écrire pour les autres (y compris moi-même dans le futur)" **. Lorsque vous apprenez des techniques de programmation ou écrivez des programmes, pas seulement orientés objet, pensez "Est-ce vraiment facile pour les autres (y compris moi-même dans le futur) de lire et de modifier?"

Recommended Posts

Qu'est-ce que l'orientation objet après tout ou juste une chose à surveiller dans la programmation
Qu'est-ce que l'orientation objet après tout?
Qu'est-ce que l'orientation objet après tout?
Points à connaître avec Java Equals
Mémo des paramètres Gradle (multi-projets pour tout en un) pour moi-même
Une introduction aux types fonctionnels pour les programmeurs orientés objet dans Elm
Qu'est-il arrivé aux modifications typiques d'Apache Wicket 8?
Qu'est-ce qu'un extrait de code en programmation?
[Pour les débutants en programmation] Qu'est-ce qu'une méthode?
Attention aux variables embarquées dans S2Dao
Eclipse Pleiades All in One version pour Mac
Après tout, que fait [rails db: migrate]?
Que faire lorsque l'adresse déjà utilisée est affichée après l'exécution des rails