/**
 * Beispiele für Polymorphie, Zuweisungskompatibilaet, explizite Typumwandlung
 *
 * @version 2002-04-09
 * @author Andreas Noack
 */

/*
  Variablen und Ausdruecke haben TYPEN, die zur Compilezeit (statisch) bestimmt
  werden koennen. Objekte haben (bzw. sind Instanzen von) KLASSEN, 
  die eventuell nicht zur Compilezeit feststehen.
  (Java Language Specification, 4.5.6, S. 52f)
  Das letzte Beispiel verdeutlicht: Explizite Typumwandlungen wandeln
  den TYP eines Ausdrucks, nicht die KLASSE eine Objekts.
*/

import java.io.*;

class A {
  public void a() {
    System.out.println("A.a()");
  }
}

class B extends A {
  public void a() {
    System.out.println("B.a()");
  }

  public void b() {
    System.out.println("B.b()");
  }
}

public class AssignCast {

  // Ausgabe: A.a()
  public static void main(String[] args) {
    A a = new A();
    a.a();
  }

  // Ausgabe: B.a() 
  public static void main(String[] args) {
    A a = new B();
    a.a();    
  }

  // Compilerfehler
  public static void main(String[] args) {
    B b = new A();
    b.a();
  }

  // Compilerfehler
  public static void main(String[] args) {
    A a = new B();
    B b = a;
  }

  // Compilerfehler
  public static void main(String[] args) {
    A a = new B();
    a.b();
  }

  // Ausgabe: B.b()
  public static void main(String[] args) {
    A a = new B();
    ((B)a).b();
  }

  // Laufzeitfehler: Exception in thread "main" java.lang.ClassCastException: A
  public static void main(String[] args) {
    A a = new A();
    ((B)a).b();
  }

  // Ausgabe: B.a() (!)
  public static void main(String[] args) {
    B b = new B();
    ((A)b).a();
  }

}
