Recherche…


Introduction

Les objets ont des états et des comportements. Exemple: un chien a des états - couleur, nom, race ainsi que comportements - qui remue la queue, aboie, mange. Un objet est une instance d'une classe.

Classe - Une classe peut être définie comme un modèle / plan directeur décrivant le comportement / état pris en charge par l'objet de son type.

Syntaxe

  • class Example {} // mot-clé de la classe, nom, corps

Classe la plus simple possible

class TrivialClass {}

Une classe comprend au minimum le mot class clé de class , un nom et un corps, qui peuvent être vides.

Vous instanciez une classe avec le new opérateur.

TrivialClass tc = new TrivialClass();

Membre d'objet vs membre statique

Avec cette classe:

class ObjectMemberVsStaticMember {

    static int staticCounter = 0;
    int memberCounter = 0;

    void increment() {
        staticCounter ++;
        memberCounter++;
    }
}

l'extrait de code suivant:

final ObjectMemberVsStaticMember o1 = new ObjectMemberVsStaticMember();
final ObjectMemberVsStaticMember o2 = new ObjectMemberVsStaticMember();

o1.increment();

o2.increment();
o2.increment();

System.out.println("o1 static counter " + o1.staticCounter);
System.out.println("o1 member counter " + o1.memberCounter);
System.out.println();

System.out.println("o2 static counter " + o2.staticCounter);
System.out.println("o2 member counter " + o2.memberCounter);
System.out.println();

System.out.println("ObjectMemberVsStaticMember.staticCounter = " + ObjectMemberVsStaticMember.staticCounter);

// the following line does not compile. You need an object
// to access its members
//System.out.println("ObjectMemberVsStaticMember.staticCounter = " + ObjectMemberVsStaticMember.memberCounter);

produit cette sortie:

o1 static counter 3
o1 member counter 1

o2 static counter 3
o2 member counter 2

ObjectMemberVsStaticMember.staticCounter = 3

Remarque: Vous ne devez pas appeler static membres static sur des objets, mais sur des classes. Bien que cela ne fasse aucune différence pour la JVM, les lecteurs humains l'apprécieront.

static membres static font partie de la classe et n'existent qu'une fois par classe. Les membres non static existent sur les instances, il existe une copie indépendante pour chaque instance. Cela signifie également que vous devez accéder à un objet de cette classe pour accéder à ses membres.

Méthodes de surcharge

Parfois, la même fonctionnalité doit être écrite pour différents types d'entrées. A ce moment, on peut utiliser le même nom de méthode avec un ensemble de paramètres différent. Chaque ensemble de paramètres différent est appelé signature de méthode. Comme vu dans l'exemple, une seule méthode peut avoir plusieurs signatures.

public class Displayer {

    public void displayName(String firstName) {
        System.out.println("Name is: " + firstName);
    }

    public void displayName(String firstName, String lastName) {
        System.out.println("Name is: " + firstName + " " + lastName);
    }

    public static void main(String[] args) {
        Displayer displayer = new Displayer();
        displayer.displayName("Ram");          //prints "Name is: Ram"
        displayer.displayName("Jon", "Skeet"); //prints "Name is: Jon Skeet"
    }
}

L'avantage est que la même fonctionnalité est appelée avec deux nombres d'entrées différents. En invoquant la méthode en fonction de l’entrée que nous transmettons (dans ce cas, une valeur de chaîne ou deux valeurs de chaîne), la méthode correspondante est exécutée.

Les méthodes peuvent être surchargées:

  1. Basé sur le nombre de paramètres transmis.

    Exemple: method(String s) et method(String s1, String s2) .

  1. Basé sur l' ordre des paramètres .

    Exemple: method(int i, float f) et method(float f, int i)) .

Remarque: Les méthodes ne peuvent pas être surchargées en modifiant uniquement le type de retour ( int method() est considéré comme identique à la String method() et lancera une RuntimeException cas de tentative). Si vous modifiez le type de retour, vous devez également modifier les paramètres pour surcharger.

Construction et utilisation d'objets de base

Les objets viennent dans leur propre classe, un exemple simple serait une voiture (explications détaillées ci-dessous):

public class Car {
    
    //Variables describing the characteristics of an individual car, varies per  object
   private int milesPerGallon;
   private String name;
   private String color;
   public int numGallonsInTank; 
    
    public Car(){
        milesPerGallon = 0;
        name = "";
        color = "";
        numGallonsInTank = 0;
    }
    
    //this is where an individual object is created
    public Car(int mpg, int, gallonsInTank, String carName, String carColor){
        milesPerGallon = mpg;
        name = carName;
        color = carColor;
        numGallonsInTank = gallonsInTank;
    }

    //methods to make the object more usable

    //Cars need to drive
    public void drive(int distanceInMiles){
        //get miles left in car
        int miles = numGallonsInTank * milesPerGallon;
        
        //check that car has enough gas to drive distanceInMiles
        if (miles <= distanceInMiles){
            numGallonsInTank = numGallonsInTank - (distanceInMiles / milesPerGallon)
            System.out.println("Drove " + numGallonsInTank + " miles!");
        } else {
            System.out.println("Could not drive!");
        }
    }

    public void paintCar(String newColor){
        color = newColor;
    }
        //set new Miles Per Gallon
    public void setMPG(int newMPG){
        milesPerGallon = newMPG;
    }

       //set new number of Gallon In Tank
    public void setGallonsInTank(int numGallons){
        numGallonsInTank = numGallons;
    }
    
    public void nameCar(String newName){
        name = newName;
    }

    //Get the Car color
    public String getColor(){
        return color;
    }

    //Get the Car name
    public String getName(){
        return name;
    }

    //Get the number of Gallons
    public String getGallons(){
        return numGallonsInTank;
    }
    
}  

Les objets sont des instances de leur classe. La manière dont vous créeriez un objet serait donc d'appeler la classe Car de deux manières différentes dans votre classe principale (méthode principale en Java ou onCreate sous Android).

Option 1

`Car newCar = new Car(30, 10, "Ferrari", "Red");

L'option 1 est l'endroit où vous racontez essentiellement au programme tout ce qui concerne la voiture lors de la création de l'objet. Toute modification de toute propriété de la voiture nécessiterait d'appeler l'une des méthodes telles que la méthode repaintCar . Exemple:

 newCar.repaintCar("Blue");

Remarque: Assurez-vous de transmettre le type de données correct à la méthode. Dans l'exemple ci-dessus, vous pouvez également passer une variable à la méthode repaintCar tant que le type de données est correct .

C'était un exemple de modification des propriétés d'un objet, la réception des propriétés d'un objet nécessiterait l'utilisation d'une méthode de la classe Car ayant une valeur de retour (c'est-à-dire une méthode non void ). Exemple:

String myCarName = newCar.getName();  //returns string "Ferrari"

L'option 1 est la meilleure option lorsque vous avez toutes les données de l'objet au moment de la création.

Option 2

`Car newCar = new Car();

L'option 2 obtient le même effet mais nécessite plus de travail pour créer un objet correctement. Je veux rappeler ce constructeur dans la classe Car:

public void Car(){
        milesPerGallon = 0;
        name = "";
        color = "";
        numGallonsInTank = 0;
    }

Notez que vous n'avez pas à transmettre de paramètres à l'objet pour le créer. Ceci est très utile lorsque vous ne possédez pas tous les aspects de l'objet, mais que vous devez utiliser les composants que vous possédez. Cela définit des données génériques dans chacune des variables d'instance de l'objet. Ainsi, si vous appelez une donnée qui n'existe pas, aucune erreur n'est générée.

Remarque: N'oubliez pas que vous devez définir les parties de l'objet plus tard avec lesquelles vous ne l'avez pas initialisé. Par exemple,

Car myCar = new Car();
String color = Car.getColor(); //returns empty string

C'est une erreur courante parmi les objets qui ne sont pas initialisés avec toutes leurs données. Les erreurs ont été évitées car il existe un constructeur qui permet de créer un objet Car vide avec des variables autonomes ( public Car(){} ), mais aucune partie de myCar n'a été réellement personnalisée. Exemple correct de création d'objet automobile:

Car myCar = new Car();
myCar.nameCar("Ferrari");
myCar.paintCar("Purple");
myCar.setGallonsInTank(10);
myCar.setMPG(30);

Et, pour rappel, obtenez les propriétés d'un objet en appelant une méthode dans votre classe principale. Exemple:

String myCarName = myCar.getName(); //returns string "Ferrari"

Constructeurs

Les constructeurs sont des méthodes spéciales nommées après la classe et sans type de retour, et sont utilisées pour construire des objets. Les constructeurs, comme les méthodes, peuvent prendre des paramètres d'entrée. Les constructeurs sont utilisés pour initialiser des objets. Les classes abstraites peuvent aussi avoir des constructeurs.

public class Hello{
    // constructor
    public Hello(String wordToPrint){
        printHello(wordToPrint);
    }
    public void printHello(String word){
        System.out.println(word);
    }
}
// instantiates the object during creating and prints out the content
// of wordToPrint

Il est important de comprendre que les constructeurs sont différents des méthodes de plusieurs manières:

  1. Les constructeurs peuvent uniquement prendre les modificateurs public , private et protected , et ne peuvent pas être déclarés abstract , final , static ou synchronized .

  2. Les constructeurs n'ont pas de type de retour.

  3. Les constructeurs DOIVENT être nommés comme le nom de la classe. Dans l'exemple Hello , le nom du constructeur de l'objet Hello est identique au nom de la classe.

  4. Le mot this clé this a une utilisation supplémentaire dans les constructeurs. this.method(...) appelle une méthode sur l'instance en cours, alors que this(...) fait référence à un autre constructeur de la classe en cours avec des signatures différentes.

Les constructeurs peuvent également être appelés par héritage en utilisant le mot super clé super .

public class SuperManClass{

    public SuperManClass(){
        // some implementation
    }
    
    // ... methods
}


public class BatmanClass extends SupermanClass{
    public BatmanClass(){
        super();
    }
    //... methods...
}

Voir Spécification du langage Java n ° 8.8 et n ° 15.9

Initialisation des champs finaux statiques à l'aide d'un initialiseur statique

Pour initialiser un static final nécessitant l'utilisation de plusieurs expressions, un initialiseur static peut être utilisé pour affecter la valeur. L'exemple suivant initialise un ensemble de String de caractères non modifiable:

public class MyClass {

    public static final Set<String> WORDS;
    
    static {
        Set<String> set = new HashSet<>();
        set.add("Hello");
        set.add("World");
        set.add("foo");
        set.add("bar");
        set.add("42");
        WORDS = Collections.unmodifiableSet(set);
    }
}

Expliquer ce qu'est la surcharge et la dérogation de la méthode.

Le remplacement de méthodes et la surcharge sont deux formes de polymorphisme supportées par Java.

Surcharge de méthode

La surcharge de méthode (également connue sous le nom de polymorphisme statique) est une façon dont vous pouvez avoir deux (ou plusieurs) méthodes (fonctions) avec le même nom dans une seule classe. Oui c'est aussi simple que ça.

public class Shape{
    //It could be a circle or rectangle or square
    private String type;
    
    //To calculate area of rectangle
    public Double area(Long length, Long breadth){
        return (Double) length * breadth;
    }
    
     //To calculate area of a circle
     public Double area(Long radius){
        return (Double) 3.14 * r * r;
    }
}

De cette façon, l'utilisateur peut appeler la même méthode pour la zone en fonction du type de forme dont il dispose.

Mais la vraie question est maintenant, comment java compiler va-t-il distinguer quel corps de méthode doit être exécuté?

Eh bien, Java a clairement indiqué que même si les noms de méthodes ( area() dans notre cas) peuvent être identiques, mais que la méthode des arguments est différente, elle devrait être différente.

Les méthodes surchargées doivent avoir une liste d'arguments différente (quantité et types).

Cela étant dit, nous ne pouvons pas ajouter une autre méthode pour calculer l'aire d'un carré comme ceci: public Double area(Long side) car dans ce cas, elle entrera en conflit avec la méthode de cercle et provoquera une ambiguïté pour le compilateur Java.

Dieu merci, il y a des relaxations en écrivant des méthodes surchargées comme

Peut avoir différents types de retour.

Peut avoir différents modificateurs d'accès.

Peut lancer différentes exceptions.

Pourquoi est-ce ce qu'on appelle le polymorphisme statique?

Eh bien, c'est parce que les méthodes surchargées à invoquer sont décidées au moment de la compilation, en fonction du nombre réel d'arguments et des types de compilation des arguments.

L'une des raisons courantes de l'utilisation de la surcharge de méthodes est la simplicité du code fourni. Par exemple rappelez-vous String.valueOf() qui prend presque n'importe quel type d'argument? Ce qui est écrit derrière la scène est probablement quelque chose comme ceci: -

static String valueOf(boolean b) 
static String valueOf(char c) 
static String valueOf(char[] data) 
static String valueOf(char[] data, int offset, int count) 
static String valueOf(double d) 
static String valueOf(float f) 
static String valueOf(int i) 
static String valueOf(long l) 
static String valueOf(Object obj) 

Dérogation de méthode

Eh bien, la méthode qui remplace (oui vous le devinez bien, c'est aussi le polymorphisme dynamique) est un sujet un peu plus intéressant et complexe.

En cas de substitution de méthode, nous écrasons le corps de la méthode fourni par la classe parente. Je l'ai? Non? Passons en revue un exemple.

public abstract class Shape{
    
    public abstract Double area(){
        return 0.0;
    }
}

Nous avons donc une classe appelée Shape et elle a une méthode appelée zone qui renverra probablement la zone de la forme.

Disons que maintenant nous avons deux classes appelées Circle et Rectangle.

public class Circle extends Shape {
    private Double radius = 5.0;

    // See this annotation @Override, it is telling that this method is from parent
    // class Shape and is overridden here
    @Override
    public Double area(){
        return 3.14 * radius * radius;
    }
}

De même classe de rectangle:

 public class Rectangle extends Shape {
    private Double length = 5.0;
    private Double breadth= 10.0;


    // See this annotation @Override, it is telling that this method is from parent
    // class Shape and is overridden here
    @Override
    public Double area(){
        return length * breadth;
    }
}

Donc, maintenant, les deux classes de vos enfants ont mis à jour le corps de la méthode fourni par la classe parent ( Shape ). Maintenant, la question est comment voir le résultat? Eh bien laisse faire le vieux moyen psvm .

public class AreaFinder{
    
    public static void main(String[] args){

        //This will create an object of circle class
        Shape circle = new Circle();
        //This will create an object of Rectangle class
        Shape rectangle = new Rectangle();
        
        // Drumbeats ......
        //This should print 78.5
        System.out.println("Shape of circle : "+circle.area());

        //This should print 50.0
        System.out.println("Shape of rectangle: "+rectangle.area());            
        
    }
}

Hou la la! n'est-ce pas génial? Deux objets de même type appelant les mêmes méthodes et renvoyant des valeurs différentes. Mon ami, c'est le pouvoir du polymorphisme dynamique.

Voici un tableau pour mieux comparer les différences entre les deux: -

Surcharge de méthode Dérogation de méthode
La surcharge de la méthode est utilisée pour améliorer la lisibilité du programme. La substitution de méthode est utilisée pour fournir l'implémentation spécifique de la méthode déjà fournie par sa super classe.
La surcharge de méthode est effectuée dans la classe. La substitution de méthode se produit dans deux classes ayant une relation IS-A (héritage).
En cas de surcharge de la méthode, le paramètre doit être différent. En cas de substitution de méthode, le paramètre doit être identique.
La surcharge de méthode est l'exemple du polymorphisme de compilation. La substitution de méthode est l'exemple du polymorphisme d'exécution.
En Java, la surcharge de la méthode ne peut pas être effectuée en modifiant uniquement le type de retour de la méthode. Le type de retour peut être identique ou différent dans la surcharge de la méthode. Mais vous devez changer le paramètre. Le type de retour doit être identique ou covariant lors de la substitution de méthode.


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow