Académique Documents
Professionnel Documents
Culture Documents
- Partie 2 -
Héritage, Interface et classe abstraite
belabdelli@3il.fr
1
Héritage
• Héritage : • Constructeurs
Concept • Héritage des méthodes
Représentation UML Accessibilité des méthodes
Les objets de la classe fille Redéfinition
• Héritage des attributs
accessibilité et masquage
2
Héritage : le concept
Consiste à définir une classe, dite classe dérivée ou classe fille, à partir
d’une autre classe, dite classe de base ou classe mère, en récupérant
automatiquement dans la classe dérivée tous les membres de la classe de
base, et en lui en ajoutant éventuellement de nouveaux membres
3
Héritage : représentation UML
4
Héritage des attributs : c’est quoi ?
Tout objet d’une classe fille est considéré comme étant un objet de la
classe mère
Un pixel coloré est avant tout un pixel
Tout objet d’une classe fille conserve tous les champs dérivés de sa
classe mère en plus de ces propres champs
Il y a un int x et un int y dans un objet de la classe ColoredPixel
#1 @class Pixel
#1 x:1
public static void main(String[] args) {
Pixel p = new Pixel(); y:1
p.moveTo(1, 1); #2
ColoredPixel cp = new ColoredPixel(); #2 @class ColoredPixel
l
cp.moveTo(2, 2);
cp.getRed(); // NullPointerException x:2
} y:2
rgb : null
5
Héritage des attributs : accessibilité
Ils peuvent être manipulés si leur accessibilité le permet
Si x n’est pas private dans Pixel, on peut dire this.x dans ColoredPixel
Ils peuvent être masqués par la définition de champs qui ont le même
nom dans la classe dérivée
Si String x est déclaré dans ColoredPixel, c’est celui qui sera considéré dans cette
classe quand on parle de this.x
Il est possible de manipuler celui qui est masqué (s’il est accessible) par la notation
super.x
6
Héritage des attributs : la résolution des accès
7
Héritage des attributs : le masquage
8
Transtypage : définition
class A { }
Le transtypage de référence est le fait class B extends A { }
de considérer explicitement (forcer) class C extends B { }
une référence comme étant d’un type
public class Test {
donné (qui n’est pas nécessairement
le type de l’objet lors de sa public static void main(String[] args) {
déclaration) B b = new B();
A a = b;
//B b2 = a; // incompatible types
B b2 = (B) a; // OK
La VM vérifiera, à l’exécution, que le C c = (C) a; // ClassCastException
type en question est bien compatible, }
}
sinon, l’exécution provoque une Object o;
ClassCastException if(Math.random() > 0.5)
o = "toto";
else
o = new Object();
String s = (String) o;
//Compile toujours mais a une
//chance sur deux de lever
//une ClassCastException
9
Transtypage : l’opérateur instanceof
10
Construction et héritage
11
Constructeurs et initialisations
12
Constructeurs et initialisation
13
Héritage des méthodes : définition
14
Héritage des méthodes : redéfinition de méthode
16
Redéfinition versus surcharge
17
Redéfinition : le cas de sameAs
On a redéfinit la méthode toString()
Donner une représentation textuelle plus précise dans ColoredPixel :
c’est facile (même signature)
On voudrait aussi redéfinir sameAs()
Actuellement, la méthode héritée est fausse !
Redéfinition: pas si simple avec la signature de sameAs()
/ / public boolean sameAs(ColoredPixel p ) { / / Surcharge e t pas r e d é f i n i t i o n
@Override
public boolean sameAs(Pixel p) {
return (x==p.x) && (y==p.y) && p.rgb[0]==rgb[0] ...
// Aïe! x and y: private access in Pixel
return super.sameAs(p) && p.rgb[0]==rgb[0] ...
// Aïe! rgb is not a field
return super.sameAs(p) && ((ColoredPixel)p).rgb[0]==rgb[0] ...
// Compile, mais si p n’en est pas un ColoredPixel... Aïe!
// Il faut utiliser instanceof...
}
18
Les INTERFACES
Définition, intérêt, utilisation et Héritage de classe et implémentation
implémentation d’interfaces
Les membres d’une interface Vérification du compilateur
Interface et héritage Héritage multiple
Interface et héritage
Héritage entre interfaces
19
Interface : définition
20
Interface : intérêt
21
Interface : utilisation
22
Interface : implémentation
public class Square implements Surfaceable{
private final double side;
public Square(double side) {
this.side = side;
} public class Rectangle implements Surfaceable {
@Override private final double height;
public double surface() { private final double width;
return side * side; public Rectangle(double height, double width) {
} this.height = height;
} this.width = width;
}
@Override
public double surface() {
return height * width;
public class Circle implements Surfaceable { }
private final double radius; }
public Circle(double radius) {
this.radius = radius;
}
@Override
public double surface() {
return Math.PI * radius * radius;
}
}
23
Les membres des interfaces
24
Interface et héritage
Surfaceable s = null ;
s = new Rectangle(2,5);
25
Héritage entre interfaces
27
Vérification du compilateur
28
Héritage multiple ?
A cause des champs (diamant)
Qui pourraient provenir de deux classes dont on hérite et qui devraient
« coexister » dans un même objet !
L’héritage multiple d’interfaces ne pose pas de problèmes
Au même titre que l’implémentation multiple d’interfaces
On « récupère » par héritage uniquement
• des déclarations de méthodes (qui ne possèdent pas de définition)
• des constantes dont la portée est limitée à l’interface dans laquelle elles sont
définies (espace de nom)
Object
A B
#1 @class C
x:int x:int
x=1 ?
x=2 ?
C
x=3 ?
x:int C c #1
29
LES CLASSES ABSTRAITES
• Définition
• Utilisation de méthode non encore définie
• Exemple
30
Classes abstraites : définition
31
Classe abstraite : utilisation de méthode non encore définie
public class AlgoOnTrucs {
public static double totalSurface(Surfaceable[] array) {
double total = 0.0;
for(Surfaceable truc : array)
total += truc.surface();
Le code de surface() ne peut être défini
return total; que dans la classe « concrète »
}
public static Surfaceable theBigger(Surfaceable[] array) {
Surfaceable bigger = array[0];
for(int i = 1; i<array.length; i++) {
if (array[i].biggerThan(bigger))
bigger = array[i];
} Mais je peux écrire un code pour
return bigger; biggerThan() qui ne dépend pas de cette
} classe concrète
public static void main(String[] args) {
Rectangle rectangle = new Rectangle(2,5);
Square square = new Square(10);
Circle circle = new Circle(1);
Surfaceable[] t = {rectangle, square, circle};
System.out.println(totalSurface(t)); // 113.1415926535898
System.out.println(theBigger(t)); // Square@a6eb38a
}
}
32
Classe abstraite : exemple
L’implémentation de la méthode biggerThan() marchera dès qu’on
l’appelera sur un objet (instance) d’une classe concrète, puisque celle-ci
aura donné l’implémentation de la méthode surface().
public abstract class Surfaceable {
public abstract double surface();
public boolean biggerThan(Surfaceable bigger)
{
return surface() > bigger.surface();
}
}
public class Rectangle extends Surfaceable {
...
} public class Circle extends Surfaceable {
... public class Square extends Surfaceable {
} private final double side;
public Square(double s i d e ) {
this.side = s i d e ;
}
@Override
public double s u r f a c e ( ) {
return side * side;
}
}
33