Polimorfizm
Przykład - http://rpodhajny.wordpress.com klasa bazowa A, oraz klasy pochodne B1, B2,, Bn (dziedziczące po klasie bazowej). niektóre klasy pochodne chcą mieć możliwość skorzystania z metody xxx() niewszytskie klasy Zadeklarowanie metody xxx() w klasie bazowej, spowoduje, że wszystkie klasy pochodne wejdą w jej posiadanie. Nowa klasa z metodą xxx(), dziedziczą z niej tylko te klasy, które chcą mieć dostęp do xxx() wielodziedziczenie
Interfejs?? interfejs X, który posiada deklarację metody xxx() każda klasa implementująca ten interfejs będzie musiała zaimplementować abstrakcyjną metodę, jaką on udostępnia.
class A { void a(){; class B1 extends A { // B1 dziedziczy metodę a() z klasy bazowej class B2 extends A implements X { // B2 dziedziczy metodę a() z klasy bazowej public void interfacemethod() { //... interface X { void interfacemethod(); public class Main { public static void main( String[] args ) { B1 b1 = new B1(); b1.a(); B2 b2 = new B2(); b2.a(); b2.interfacemethod(); // dzięki implementacji interfejsu, obiekt b2 zyskał nowe możliwości
obiekt b2 jest jednocześnie obiektem klasy B2 klasy A dziedziczenie Interfejsu X implementuje ten interfejs klasy Object wszystkie klasy w Javie wywodzą się z klasy Object
polimorfizm Obiekt b2 może być traktowany (w zależności od potrzeby) jako obiekt klasy: B2, A, X Object.
instanceof potrzeba zebrania w jednym miejscu wszystkich obiektów typu A, operator instanceof zwraca true, jeżeli obiekt po lewej stronie nalezy do klasy po prawej jego stronie. object instanceof type
Przykład - http://www.java-samples.com class A { int i, j; class B { int i, j; class C extends A { int k; class D extends A { int k; class InstanceOf { public static void main(string args[]) { A a = new A(); B b = new B(); C c = new C(); D d = new D();
if(a instanceof A) System.out.println("a is instance of A"); if(b instanceof B) System.out.println("b is instance of B"); if(c instanceof C) System.out.println("c is instance of C"); if(c instanceof A) System.out.println("c can be cast to A"); if(a instanceof C) System.out.println("a can be cast to C"); System.out.println(); a is instance of A b is instance of B c is instance of C c can be cast to A
D d = new D(); A ob; ob = d; // A reference to d System.out.println("ob now refers to d"); if(ob instanceof D) System.out.println("ob is instance of D"); System.out.println(); ob now refers to d ob is instance of D ob = c; // A reference to c System.out.println("ob now refers to c"); if(ob instanceof D) System.out.println("ob can be cast to D"); else System.out.println("ob cannot be cast to D"); if(ob instanceof A) System.out.println("ob can be cast to A"); ob now refers to c ob cannot be cast to D ob can be cast to A
if(a instanceof Object) System.out.println("a may be cast to Object"); if(b instanceof Object) System.out.println("b may be cast to Object"); if(c instanceof Object) System.out.println("c may be cast to Object"); if(d instanceof Object) System.out.println("d may be cast to Object"); a may be cast to Object b may be cast to Object c may be cast to Object d may be cast to Object
Przykład rzutowanie w górę 'Thinking in Java, 3rd ed.' (c) Bruce Eckel 2002 //: c07:music:note.java - Nuty grane na instrumentach muzycznych. package c07.music; import com.bruceeckel.simpletest.*; public class Note { private String notename; private Note(String notename) { this.notename = notename; public String tostring() { return notename; stałe obiekty, które możemy używać, ale nie tworzyć public static final Note MIDDLE_C = new Note("Środkowe C"), C_SHARP = new Note("C wysokie"), B_FLAT = new Note("B z bemolem");
package c07.music; public class Instrument { public void play(note n) { System.out.println("Instrument.play() " + n); package c07.music; // Obiekty Wind są instrumentami (Instrument) gdyż mają ten sam interfejs public class Wind extends Instrument { public void play(note n) { System.out.println("Wind.play() " + n);
// Dziedziczenie i rzutowanie w górę. package c07.music; import com.bruceeckel.simpletest.*; public class Music { public static void tune(instrument i) { //... i.play(note.middle_c); public static void main(string[] args) { Wind flute = new Wind(); tune(flute); // Rzutowanie w górę Wind staje się Instrument... ///:~ "Wind.play() Środkowe C"
package c07.music; import com.bruceeckel.simpletest.*; przeciążenie class Stringed extends Instrument { public void play(note n) { System.out.println("Stringed.play() " + n); class Brass extends Instrument { public void play(note n) { System.out.println("Brass.play() " + n);
public class Music2 { public static void tune(wind i) { i.play(note.middle_c); public static void tune(stringed i) { i.play(note.middle_c); public static void tune(brass i) { i.play(note.middle_c); public static void main(string[] args) { Wind flute = new Wind(); Stringed violin = new Stringed(); Brass frenchhorn = new Brass(); tune(flute); // Brak rzutowania w górę tune(violin); tune(frenchhorn); ///: Wind.play() Środkowe C Stringed.play() Środkowe C Brass.play() Środkowe C
Przygotowanie jednej metody pobierającej obiekt klasy bazowej? Wiązanie: wczesne na etapie kompilacji późne na etapie wykonywania programu public static void tune(instrument i) { //... i.play(note.middle_c);
Rzutowanie w górę: Shape s=new Circle(); s.draw(); draw() z Shape draw() z Circle
class Shape { void draw() { void erase() { class Circle extends Shape { void draw() { System.out.println("Circle.draw()"); void erase() { System.out.println("Circle.erase()"); class Square extends Shape { void draw() { System.out.println("Square.draw()"); void erase() { System.out.println("Square.erase()"); class Triangle extends Shape { void draw() { System.out.println("Triangle.draw()"); void erase() { System.out.println("Triangle.erase()");
// "Fabryka", która w losowy sposób tworzy figury: class RandomShapeGenerator { private Random rand = new Random(); public Shape next() { switch(rand.nextint(3)) { default: Rzutowanie w górę case 0: return new Circle(); case 1: return new Square(); case 2: return new Triangle(); public class Shapes { private static RandomShapeGenerator gen =new RandomShapeGenerator(); public static void main(string[] args) { Shape[] s = new Shape[9]; for(int i = 0; i < s.length; i++) // Wypełnienie tablicy figurami s[i] = gen.next(); for(int i = 0; i < s.length; i++) //Polimorficzne wywołania metody s[i].draw();