OVH Cloud OVH Cloud

abstract ou non abstract ?

3 réponses
Avatar
Julien Cigar
Bonjour,

Je suis en train d'apprendre le Java et j'ai une question sur les classes
abstract. En fait je comprend le principe, mais je ne vois pas la
différence entre la redefinition dans des sous classes.

Imaginez que l'on doive faire un support de plusieurs bases de données
(dans mon exemple 2 : Mysql et Postgresql).
On demande d'implementer les methodes connect() et
disconnect() et doQuery(String query) qui est commune aux 2.

Quelle serait la différence entre faire (je simplifie) :

Public class dbGlobal
{
public void doQuery(){ // code }
}

Public class Mysql extends dbGlobal
{
public void connect(){ // code }
public void disconnect(){ // code}
}

Public class Postgres extends dbGlobal
{
public void connect(){ // code }
public void disconnect(){ // code}
}

========================
et faire :
========================

Public abstract class dbGlobal
{
public doQuery(){ // code }
public abstract void connect();
public abstract void disconnect();
}

Public class Mysql extends dbGlobal
{
public void connect(){ // code }
public void disconnect(){ // code}
}

Public class Postgres extends dbGobal
{
public void connect(){ // code }
public void disconnect(){ // code}
}


D'avance merci pour vos réponses

3 réponses

Avatar
Mat Free
Je suis en train d'apprendre le Java et j'ai une question sur les classes
abstract. En fait je comprend le principe, mais je ne vois pas la
différence entre la redefinition dans des sous classes.

Imaginez que l'on doive faire un support de plusieurs bases de données
(dans mon exemple 2 : Mysql et Postgresql).
On demande d'implementer les methodes connect() et
disconnect() et doQuery(String query) qui est commune aux 2.

Quelle serait la différence entre faire (je simplifie) :

Public abstract class dbGlobal
{
public doQuery(){ // code }
public abstract void connect();
public abstract void disconnect();
}


Cet exemple me parait plus correct étant donné
que la classe dbGlobal n'a pas à être instanciée
sans avoir été spécialisée. Pour le abstract
devant connect et disconnect, ça peut se discuter,
tu pourrai avoir besoin de faire un traitement commun
a tous les types de bases (modification d'un booléen
connecté ou non, ...)

--
Mat

Avatar
Christophe M
Mat Free wrote:
Je suis en train d'apprendre le Java et j'ai une question sur les classes
abstract. En fait je comprend le principe, mais je ne vois pas la
différence entre la redefinition dans des sous classes.

Imaginez que l'on doive faire un support de plusieurs bases de données
(dans mon exemple 2 : Mysql et Postgresql).
On demande d'implementer les methodes connect() et
disconnect() et doQuery(String query) qui est commune aux 2.

Quelle serait la différence entre faire (je simplifie) :



Public abstract class dbGlobal
{
public doQuery(){ // code }
public abstract void connect();
public abstract void disconnect();
}



Cet exemple me parait plus correct étant donné
que la classe dbGlobal n'a pas à être instanciée
sans avoir été spécialisée. Pour le abstract
devant connect et disconnect, ça peut se discuter,
tu pourrai avoir besoin de faire un traitement commun
a tous les types de bases (modification d'un booléen
connecté ou non, ...)



Je suis d'accord, c'est plus mieux comme ça.
ça permet aussi d'avoir le même type de base utilisable partout (càd
dbGlobal ), sur lequel tu peux appeler connect() et disconnect().

Et le abstract devant ces méthodes est obligatoire si tu n'implémentes
pas ces méthodes dans dbGlobal. Sinon, pour par exemple la gestion d'un
boolean commun , il faut évidemment enlever l'abstract. et surtout
penser à faire un super.dis/connect() dans les classes mysql et postgres

le gros interet c'est d'utiliser le type dbGlobal partout dans ton code,
et le jour ou tu veux passer sur Oracle, tu écrit simplement le driver
et tu change ta méthode de création (d'ou l'interet de passer par un
factory), le reste du code est tjrs valable puisque travaillant sur le
type dbGlobal dont dérivera ton nouveau "driver".


Avatar
Xavier Tarrago
La première différence, c'est que si on a un objet dbGlobal, dans le 2eme
cas, on peut faire
dbGlobal db = ...
db.connect();
Dans le premier on ne peut pas. Et donc, on ne peut pas faire par exemple :
Result = getResult(dbGlobal db) {
Connection cnx = db.connect();
Result res = cnx.getQuery("ma requete");
db.disconnect();
}
Ca, c'est plutot l'utilisation d'une méthode abstraite. Une méthode
abstraite, c'est au niveau d'une classe la garantie que cette méthode
existera dans la classe réelle, meme si a ce stade, on n'est pas capable de
la réaliser. Par exemple,
public abstract void connect();
dans la classe dbGlobal signifie : Toute classe réelle dérivant de dbGlobal
aura cette méthode meme si elle est différente suivant les classes réelles
(on dit concrètes). En général, cela s'accompagne d'un contrat sémantique,
par exemple, "cette méthode ouvre une connection sur la base de donnée". La
réalisation concrète de cette méthode dépendra de la base de donnée.

Une classe abstraite est une classe qui ne peut être instanciée telle
quelle, mais seulement être dérivée.
Une classe qui contient des méthodes abstraites doit évidemment être
abstraite.
Par contre, l'intérêt de classes abstraites sans méthodes abstraites
m'échappe un peu. Ca peu être utile si on a une classe avec des méthodes
avec des implémentations par défaut, donc aucune n'est abstraite, mais qu'on
veut exprimer que cette classe ne peut être utilisée que comme une base de
dérivation...

"Julien Cigar" a écrit dans le message de
news:
Bonjour,

Je suis en train d'apprendre le Java et j'ai une question sur les classes
abstract. En fait je comprend le principe, mais je ne vois pas la
différence entre la redefinition dans des sous classes.

Imaginez que l'on doive faire un support de plusieurs bases de données
(dans mon exemple 2 : Mysql et Postgresql).
On demande d'implementer les methodes connect() et
disconnect() et doQuery(String query) qui est commune aux 2.

Quelle serait la différence entre faire (je simplifie) :

Public class dbGlobal
{
public void doQuery(){ // code }
}

Public class Mysql extends dbGlobal
{
public void connect(){ // code }
public void disconnect(){ // code}
}

Public class Postgres extends dbGlobal
{
public void connect(){ // code }
public void disconnect(){ // code}
}

======================= > et faire :
======================= >
Public abstract class dbGlobal
{
public doQuery(){ // code }
public abstract void connect();
public abstract void disconnect();
}

Public class Mysql extends dbGlobal
{
public void connect(){ // code }
public void disconnect(){ // code}
}

Public class Postgres extends dbGobal
{
public void connect(){ // code }
public void disconnect(){ // code}
}


D'avance merci pour vos réponses