Ένα από τα καλύτερα θέματα εξετάσεων που ενδείκνυται για επανάληψη και εξάσκηση στην κατανόηση των interface,  abstract κλάσεων, σχέσεις των κλάσεων μεταξύ τους και υλοποίηση μεθόδων είναι αυτό του 2011-12 και το Θέμα 3.
Καλύπτει ένα μεγάλο αν όχι το σύνολο του προγραμματισμού σε java καθώς δίνει απαντήσεις στα περισσότερα και δυσκολότερα αλλά και ουσιαστικά ζητήματα του αντικειμενοστραφούς προγραμματισμού.

Στην συνέχεια παραθέτουμε τον κώδικα για περαιτέρω μελέτη που είναι απαραίτητη για την κάλυψη ενός μεγάλου μέρους της ύλης.

Δίνεται ο παρακάτω κώδικας Java:

public interface Inter1 {
void m1();
}

public interface Inter2 extends Inter1 {
void m2();
}
public class C1 {
public String mC1() {
return "I am in method mC1 of class C1";
}
public String toString() {
return "toString() method of class C1";
}
}
public class C2 extends C1 implements Inter2 {
public void m1() {
System.out.println("I am in method m1 of class C2");
}
public void m2() {
System.out.println("I am in method m2 of class C2");
}
}
public class C3 implements Inter2{
public void m1() {
System.out.println("I am in method m1 of class C3");
}
public void m2() {
System.out.println("I am in method m2 of class C3");
}
}
public abstract class A implements Inter2 {
public void m1() {
}
}

public class JavaApp1 {
public static void main(String[] args) {
Inter1 i1 = new C2();
i1.m1();
i1.m2();
Inter2 i2 = new C2();
i2.m1();
i2.m2();
String s1 = i1.mC1();
String s4 = i1.toString();
System.out.println("s4 : " + s4);
String s5 = i2.toString();
System.out.println("s5 : " + s5);
Inter1 i3 = new C3();
String s6 = i3.toString();
System.out.println("s6 : " + s6);
Object o1 = new C2();
o1.m1();
((C3)o1).m1();
}
}

Ερώτημα 1

Ο κώδικας της main περιέχει 4 σφάλματα. Να τα εντοπίσετε και να εξηγήσετε γιατί θεωρείτε
καθένα από αυτά ως σφάλμα.

Ερώτημα 2

Στη συνέχεια να παραθέσετε τον κώδικα, ο οποίος κατά τη γνώμη σας διορθώνει καθένα από
τα σφάλματα

Ερώτημα 3

Τέλος, να γράψετε το αποτέλεσμα (έξοδος) της εκτέλεσης του διορθωμένου κώδικα

Απάντηση:

Στο ερώτημα 1,Στο ερώτημα 2, Στο ερώτημα 3

public interface Inter1 {
void m1();
}
public interface Inter2 extends Inter1 {
void m2();
}
public class C1 {
public String mC1() {
return "I am in method mC1 of class C1";
}
public String toString() {
return "toString() method of class C1";
}
}
public class C2 extends C1 implements Inter2 {
public void m1() {
System.out.println("I am in method m1 of class C2");
}
public void m2() {
System.out.println("I am in method m2 of class C2");
}
}
public class C3 implements Inter2{
public void m1() {
System.out.println("I am in method m1 of class C3");
}
public void m2() {
System.out.println("I am in method m2 of class C3");
}
}
public abstract class A implements Inter2 {
public void m1() {
}
}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package javaapp1;
public class JavaApp1 {
public static void main(String[] args) {
// TODO code application logic here
Inter1 i1 = new C2();
i1.m1(); // OK αφού η m1 υπάρχει στην C2
// i1.m2(); // Σφάλμα αφού η m2 δεν υπάρχει στο Inter1

//*** BEGIN Απάντηση i)
 ((Inter2) i1).m2(); // Casting για την μετατροπή του τύπου
της αναφοράς i1 από τύπο Inter1 σε τύπο Inter2
//*** END Απάντηση i)
Inter2 i2 = new C2();
i2.m1(); // OK
i2.m2(); // OK
/// String s1 = i1.mC1(); // Σφάλμα αφού η mC1 δεν υπάρχει στο Inter1
/
/*** BEGIN Απάντηση ii)... και για αυτό η αναφορά i1
χρειάζεται μετατροπή (casting) για να μπορεί να καλεί την mC1()
String s2 = ((C1) i1).mC1();
System.out.println("s2 : " + s2);
String s3 = ((C2) i1).mC1();
System.out.println("s3 : " + s3);
//*** END Απάντηση ii)
String s4 = i1.toString();
System.out.println("s4 : " + s4);
String s5 = i2.toString();
System.out.println("s5 : " + s5);
Inter1 i3 = new C3();
String s6 = i3.toString();
System.out.println("s6 : " + s6);
Object o1 = new C2();
//// o1.m1(); // Σφάλμα αφού η κλάση Object δεν ορίζει τη μέθοδο mC1()

//*** BEGIN Απάντηση iii)
// για να λύσουμε το πρόβλημα κανουμε downcast την αναφορά
o1.
// με έναν από τους παρακάτω 3 τρόπους:
((Inter1) o1).m1(); // 1
((Inter2) o1).m1(); // 2
((C2) o1).m1(); // 3
//*** END Απάντηση iii)
((C3)o1).m1();//Σφάλμα ClassCastException, η κλάση C2 δεν
έχει καμία σχέση με την C3 παρα μόνο ότι υλοποιούν και οι δύο το
Inter2
}
}
OUTPUT
I am in method m1 of class C2
I am in method m2 of class C2
I am in method m1 of class C2
I am in method m2 of class C2
s2 : I am in method mC1 of class C1
s3 : I am in method mC1 of class C1
s4 : toString() method of class C1
s5 : toString() method of class C1
s6 : javaapp1.C3@64c3c749
I am in method m1 of class C2
I am in method m1 of class C2
I am in method m1 of class C2
Exception in thread "main" java.lang.ClassCastException: javaapp1.C2
cannot be cast to javaapp1.C3 at
javaapp1.JavaApp1.main(JavaApp1.java:60)