SlideShare a Scribd company logo
Άσκηση Μισθοδοσίας/Employee (υλοποίηση κληρονομικότητας)
Η μισθοδοσία των υπαλλήλων μιας εταιρείας περιλαμβάνει 2 κατηγορίες υπαλλήλων:
1. Tους Διοικητικούς
2. Tους Τεχνικούς.
Για τις 2 κατηγορίες υπάρχουν δύο τύποι μισθοδοσίας
• 0=Μισθωτός
• 1=Ωρομίσθιος.
Ο βασικός μισθός για τους Διοικητικούς είναι 1200 Ευρώ και για τους Τεχνικούς 800 Ευρώ, ενώ και οι 2
κατηγορίες μπορούν να λάβουν και ένα bonus (X)-Ευρώ. Ο μισθός υπολογίζεται με την σχέση: Μισθός =
Βασικός + Βonus, για τους μισθωτούς και για τους ωρομίσθιους με τη σχέση: Μισθός = Ώρες Εργασίας *
Τιμή Ώρας (όπου για τον Διοικητικό είναι 12 Ευρώ την ώρα, και για τον Τεχνικό 10 Ευρώ/ώρα).
Η υπερκλάση: Employee, θα ορίζει 4 χαρακτηριστικά που είναι κοινά και για τις δύο κατηγορίες
(1) Name, (2) Bonus, (3) Hours (για τους ωρομίσθιους) και (4) Τύπος Υπάλληλου (0=Διοικητικός, 1=Τεχνικός)
θα υλοποιεί τις μεθόδους
1. getPayType() που επιστρέφει τα μηνύματα ‘Μισθός’ ή ‘Με την Ώρα’ ανάλογα του τύπου
μισθοδοσίας
2. getEmpType() που επιστρέφει το μήνυμα “Employee type=Τύπος εργαζομένου”
3. calcSalary(), που υπολογίζει τον μισθό του Employee.
Οι υποκλάσεις: Administrator και Technical θα κληρονομούν τα 4-χαρακτηριστικά και την μέθοδο getPayType()
από την υπερκλάση, ενώ θα υπερβαίνουν (override) τις μεθόδους getEmpType() και calcSalary().
Χρησιμοποιήστε μια βοηθητική κλάση την Company στην οποία αρχικοποιείται ένας πίνακας 4-
αντικειμένων όλων των τύπων και επιπλέον 2 μεθόδους (α) setEmployee(), που εισάγει τα αντικείμενα στον
πίνακα και (β) printAll() που εμφανίζει τα στοιχεία του κάθε υπάλληλου και τον μισθό του.
Άσκηση Μισθοδοσίας/Employee (υλοποίηση κληρονομικότητας)
Η μισθοδοσία των υπαλλήλων μιας εταιρείας περιλαμβάνει 2 κατηγορίες υπαλλήλων:
1. Tους Διοικητικούς
2. Tους Τεχνικούς.
Για τις 2 κατηγορίες υπάρχουν δύο τύποι μισθοδοσίας
• 0=Μισθωτός
• 1=Ωρομίσθιος.
Ο βασικός μισθός για τους Διοικητικούς είναι 1200 Ευρώ και για τους Τεχνικούς 800 Ευρώ, ενώ και οι 2
κατηγορίες μπορούν να λάβουν και ένα bonus (X)-Ευρώ. Ο μισθός υπολογίζεται με την σχέση: Μισθός =
Βασικός + Βonus, για τους μισθωτούς και για τους ωρομίσθιους με τη σχέση: Μισθός = Ώρες Εργασίας *
Τιμή Ώρας (όπου για τον Διοικητικό είναι 12 Ευρώ την ώρα, και για τον Τεχνικό 10 Ευρώ/ώρα).
Η υπερκλάση: Employee, θα ορίζει 4 χαρακτηριστικά που είναι κοινά και για τις δύο κατηγορίες
(1) Name, (2) Bonus, (3) Hours (για τους ωρομίσθιους) και (4) Τύπος Υπάλληλου (0=Διοικητικός, 1=Τεχνικός)
θα υλοποιεί τις μεθόδους
1. getPayType() που επιστρέφει τα μηνύματα ‘Μισθός’ ή ‘Με την Ώρα’ ανάλογα του τύπου
μισθοδοσίας
2. getEmpType() που επιστρέφει το μήνυμα “Employee type=Τύπος εργαζομένου”
3. calcSalary(), που υπολογίζει τον μισθό του Employee.
Οι υποκλάσεις: Administrator και Technical θα κληρονομούν τα 4-χαρακτηριστικά και την μέθοδο getPayType()
από την υπερκλάση, ενώ θα υπερβαίνουν (override) τις μεθόδους getEmpType() και calcSalary().
Χρησιμοποιήστε μια βοηθητική κλάση την Company στην οποία αρχικοποιείται ένας πίνακας 4-
αντικειμένων όλων των τύπων και επιπλέον 2 μεθόδους (α) setEmployee(), που εισάγει τα αντικείμενα στον
πίνακα και (β) printAll() που εμφανίζει τα στοιχεία του κάθε υπάλληλου και τον μισθό του.
Απόκρυψη Πεδίων (Hiding Fields)
• Στην υποκλάση ένα πεδίο με το ίδιο όνομα πεδίου της υπερκλάσης ‘κρύβει’ το πεδίο
της υπερκλάσης ακόμη και αν είναι διαφορετικού τύπου. Στην υποκλάση, για να έχουμε
πρόσβαση στο πεδίο της υπερκλάσης χρησιμοποιούμε τη super.
• Η απόκρυψη πεδίων κάνει δύσκολη την αναγνωσιμότητα του κώδικα, για αυτό
πρέπει να την αποφεύγουμε.
• Το πεδίο στην υποκλάση με το ίδιο όνομα της υποκλάσης είναι ένα νέο πεδίο, το
πεδίο της υπερκλάσης είναι κρυμμένο και δεν μπορούμε να το υπερβούμε. Δεν
υπάρχει υπέρβαση πεδίων, όπως γίνεται με τις μεθόδους.
• Πρόσβαση σε κρυμμένα πεδία έχουμε με:
(α) χρήση αναφοράς υπερκλάσης (δες το παράδειγμα)
(β) χρήση casting: System.out.println(((Super)c1).s);
Απόκρυψη Πεδίων (Hiding Fields)
Παράδειγμα
class SuperClass
{ String f = "Yperklasi";}
class SubClass extends SuperClass
{String f = "Ypoklasi";}
public class YpervasiPediou {
public static void main(String[]
args) { SubClass p1 = new
SubClass();
System.out.println(p1.f);
SuperClass p2 = new SubClass(); //αναφορά
υπερκλάσης System.out.println(p2.f);
System.out.println(((SuperClass)p1).f); //casting
}
}
Πολυμορφισμός (Polymorphism)
Χρησιμοποιούμε Πολυμορφισμό υποκλάσης για να εκτελέσουμε
διαφορετικές μορφές της ίδιας μεθόδου.
Πολυμορφισμό έχουμε:
• Όταν ο αποστολέας ενός μηνύματος δεν χρειάζεται να γνωρίζει την
κλάση του παραλήπτη (στιγμιότυπου).
• Όταν μια λειτουργία μπορεί να υλοποιηθεί με το ίδιο όνομα αλλά
με διαφορετικό περιεχόμενο σε διαφορετικές κλάσεις (τρόπο
λειτουργίας).
• Στον πολυμορφισμό μια μεταβλητή της υπερκλάσης αναφέρεται
σε ένα αντικείμενο της υποκλάσης. Έτσι παρέχεται η
δυνατότητα σε μια μεταβλητή αναφοράς αντικειμένου να αλλάζει
συμπεριφορά (εκτελεί διαφορετικές μεθόδους) ανάλογα με το
αντικείμενο στο οποίο αναφέρεται την κάθε φορά.
Πολυμορφισμός (Polymorphism)
• Ο πολυμορφισμός αναφέρεται στη δυνατότητα να χειριζόμαστε
αντικείμενα που ανήκουν στην ίδια ιεραρχία κλάσεων, σαν να ήταν
αντικείμενα της υπερκλάσης. Για την επίτευξη πολυμορφικής
συμπεριφοράς απαιτείται μία ιεραρχία κλάσεων και υπερκαλυπτόμενες
μέθοδοι.
Πολυμορφισμός (Polymorphism)
class Animal
{
void sound() {System.out.println("Animal Sound");}
}
class Cat extends Animal
{
void sound() {// Overriding
System.out.println("Cat Sound: miaou"); }
}
class Dog extends Animal
{
void sound() {// Overriding
System.out.println("Dog Sound: wooof");} }
class testPoly {
public static void main(String[] args)
{ Animal animal = new Animal();
animal.sound();
Cat cat = new Cat();
cat.sound();
Dog dog = new Dog();
dog.sound();
System.out.println();
System.out.println("Poly-1: Animal c = new Cat();");
System.out.println(" ");
Animal c = new Cat(); //ότι η κλάση και όχι η αναφορά
// η cat sound()
c.sound();
System.out.println();
System.out.println("Poly-2: Animal c = new Dog();");
System.out.println(" ");
Animal d = new Dog(); //ότι η κλάση και όχι η αναφορά
//dog sound()
d.sound();
} }
Πολυμορφισμός Yποκλάσης
(Upcasting - Downcasting)
Animal
Mammal Reptile
Cat Dog
Object
Upcasting
downcasting
• Casting: Η ανάθεση του αντικειμένου ενός τύπου
σε αναφορά άλλου τύπου.
• Επιτρέπονται castings μόνο μεταξύ αντικειμένων
σε μια ιεραρχία κληρονομικότητας.
• Upcasting: Η ανάθεση ενός αντικειμένου της
υποκλάσης σε αναφορά της υπερκλάσης.
Δεν χρειάζεται κάποιο προσδιοριστικό, γιατί η
υποκλάση είναι μια εξειδίκευση της υπερκλάσης.
π.χ. Animal c = new Cat(); //late binding
• Δεν αλλάζει το αντικείμενο Cat αλλά το χειρίζεσαι
σαν οποιοδήποτε άλλο αντικείμενο της Animal.
Κρύβεις τις ιδιότητες της Cat, μέχρι να το κάνεις
ξανά downcast σε Cat.
Cat c = new Cat();
System.out.println(c);
Mammal m = c;
//Cat@a90653
// upcasting
System.out.println(m); //Cat@a90653
Το αντικείμενο Cat δεν άλλαξε μετά το
upcasting, αλλά μετονομάστικε σε Mammal.
Όμως δεν γίνεται cast σε Dog.
Οι ορισμοί (1) Mammal m=new Cat(); και
(2) Mammal m=(Mammal)new Cat(); Είναι
ισοδύναμοι. Ο (2) δεν απαιτείται.
Πολυμορφισμός Yποκλάσης
(Upcasting - Downcasting)
• Το downcasting (από την υπερκλάση στην υποκλάση) δεν γίνεται αυτόματα, αλλά ρητά
προγραμματιστικά (τον τύπο μέσα σε αγκύλες).
Cat c1 = new Cat();
Animal a = c1;
Cat c2 = (Cat) a;
//αυτόματο upcasting σε Animal
// downcasting σε αντικείμενο τύπου Cat
• Πριν από κάποιο downcasting μπορούμε να ελέγξουμε τον τύπο του αντικειμένου με την
instanceof. Π.χ.
Cat c1 = new Cat();
Animal a = c1; //upcasting σε Animal
// έλεγχος αν το Animal είναι ένα αντικείμενο Cat
if(a instanceof Cat)
{
System.out.println(“Einai antikeimeno Cat”);
Cat c2 = (Cat)a; //ασφαλές downcasting
}
Πολυμορφισμός Yποκλάσης
(Upcasting - Downcasting)
Upcasting μέσω της κλήσης μεθόδου
public static void walk(Animal a) {
System.out.println(“Animal walk "+a);
}
: :
Cat c = new Cat();
Dog d = new Dog();
walk(c);
walk(d);
// αυτόματο upcast σε Animal
// αυτόματο upcast σε Animal
Downcasting μέσω της κλήσης μεθόδου
class Animal { }
class Dog extends Animal
{ static void method(Animal a)
{
Dog d=(Dog)a; //downcasting
System.out.println("ok to downcasting egine");}
public static void main (String [] args) {
Animal a=new Dog();
Dog.method(a); }}
Πολυμορφισμός Yποκλάσης
(Upcasting - Downcasting)
class A
{ public A()
{
System.out.println("Domitis A");}
public String toString(){return "toString() klasis A";
}}
class B extends A
{ public B() {
super();
System.out.println("Domitis B");}
@Override
public String toString() {
return "Ypervasi-toString() klasis B";}}
class C extends B
{ public C() {
super();
System.out.println("Domitis C");}
@Override
public String toString() {
return "Ypervasi-toString() klasis C";}}
public class TestCasting {
public static void main(String[] args) {
A a1 = new C(); // ok, upcast
System.out.println(a1); //ekteleitai toString() tis C-klasis
B b1 = (B)a1;
System.out.println(b1);
C c1 = (C)b1;
System.out.println(c1);
A a2 = new B();
System.out.println(a2);
B b2 = (B)a2;
System.out.println(b2);
// ok, downcast
// -->>--metonomasia tou
// antikeimenou se B1
// ok, downcast
//-->>--metonomasia tou
// antikeimenou se C1
// ok, upcast
//ekteleitai toString() tis B-klasis
// ok, downcast
//-->>--metonomasia tou
//antikeimenou se b2
}
}
Αφηρημένες Κλάσεις (abstract classes)
Αφηρημένοι Τύποι Δεδομένων (Abstract Data Types – ADT):
Αφηρημένες κλάσεις και Διεπαφές/Διασυνδέσεις
Αφηρημένη κλάση (abstract class) είναι μια κλάση που αντιπροσωπεύει μια ευρεία
κατηγορία τύπων και ορίζεται μόνο για να κληρονομηθεί (επεκταθεί) από θυγατρικές
υποκλάσεις (π.χ. liquid, people, mammal, employee, κλπ.)
Σύνταξη (η δεσμευμένη λέξη abstract):
(1) κλάση: <visibility> abstract class <name> { }
(2) μέθοδος: <visibility> abstract <type> <name> ([parameters]);
Κανόνες και Συνθήκες:
• Δεν μπορούμε να δημιουργήσουμε αντικείμενα μιας αφηρημένης κλάσης (τελεστής new),
αλλά μπορούμε να ορίσουμε δομητές (και να έχουμε πρόσβαση από τους δομητές
των υποκλάσεων).
• Μια αφηρημένη μέθοδος δεν μπορεί να υπάρχει σε μια μη αφηρημένη κλάση. Αν μια
υποκλάση δεν υλοποιεί όλες τις αφηρημένες μεθόδους, τότε πρέπει να δηλωθεί abstract.
Αφηρημένες Κλάσεις (abstract classes)
• Η αφηρημένη κλάση ορίζει απλώς ένα "συμβόλαιο" το οποίο θα πρέπει να
ακολουθούν οι υποκλάσεις της όσον αφορά τις υπογραφές των μεθόδων
τους.
• Οι αφηρημένες μέθοδοί της είναι απλώς ένας ορισμός της υπογραφής
τους και εναπόκειται στις υποκλάσεις να τις ορίσουν και υλοποιήσουν
(συμβόλαιο).
• Δηλαδή, η αφηρημένη μέθοδος δεν έχει σώμα και τελειώνει με το (;)
• Οι αφηρημένες μέθοδοι πρέπει να είναι public (ή protected),
όχι private.
• Ο όρος abstract δεν μπορεί να χρησιμοποιηθεί σε στατικές μεθόδους ή
δομητές.
Αφηρημένες Κλάσεις (abstract classes)
• Μία αφηρημένη κλάση μπορεί να έχει και μη αφηρημένες μεθόδους οι
οποίες υλοποιούνται στην ίδια την κλάση (αν και μπορούμε να τις
υπερβούμε στις υποκλάσεις). Αν δεν περιέχει καμία abstract μέθοδο
λειτουργεί μεν σαν υπερκλάση, ωστόσο δεν μπορούμε να ορίσουμε
αντικείμενα της (τελεστής new).
• Μια υποκλάση μπορεί να δηλωθεί abstract, ακόμη και αν η υπερκλάση
είναι μη abstract.
• Μια abstract κλάση μπορεί να χρησιμοποιηθεί σαν τύπος δεδομένων π.χ.
Array - αντικειμένων, τότε μπορούμε να χρησιμοποιήσουμε τον τελεστή new.
π.χ. People[ ] objs = new People[5];
Μετά γεμίζουμε τον πίνακα με αναφορές αντικειμένων, υποκλάσεων:
π.χ. People [0]= new Student(); (πολυμορφική συμπεριφορά)
Αφηρημένες Κλάσεις (abstract classes)
Παράδειγμα :
Δημιουργούμε δύο Shape – αντικείμενα: ένα κύκλο και ένα ορθογώνιο που υλοποιούν τις
δύο abstract μεθόδους getArea() και getPerimeter().
abstract class Shape
{ private String color;
private boolean filled;
/** Abstract method getArea */
public abstract double getArea();
/** Abstract method getPerimeter */
public abstract double getPerimeter(); }
class Circle extends Shape {
private double radius;
public Circle(double r) {this.radius = r;}
public void setRadius(double r) {this.radius = r;}
public double getRadius() {return radius;}
@Override /** Return area */
public double getArea()
{return radius * radius * Math.PI;}
public double getDiameter()
{return 2 * radius;}
@Override /** Return perimeter */
public double getPerimeter()
{return 2 * radius * Math.PI;}
public void printCircle()
{ System.out.println("The radius
is
+ radius);} }
Αφηρημένες Κλάσεις (abstract classes)
class Rectangle extends Shape {
private double width;
private double height;
public Rectangle(double width, double
height) {
this.width = width;
this.height = height;}
public double getWidth()
{return width;}
public void setWidth(double width)
{this.width = width;}
public double getHeight()
{return height;}
public void setHeight(double height)
{this.height = height;}
@Override /** Return area */
public double getArea()
{return width * height;}
@Override /** Return perimeter */
public double getPerimeter()
{return 2 * (width + height);}}
class TestShape {
public static void main(String[] args) {
Shape Object1 = new Circle(8);
Shape Object2 = new Rectangle(2, 4);
// Display circle
displayObject(Object1);
// Display rectangle
displayObject(Object2); }
public static void displayObject(
Shape object)
{ System.out.println("The area is "
+
object.getArea());
System.out.println("The perimeter is «
+ object.getPerimeter()); } }
Διεπαφές (Interfaces)
Η Διεπαφή περιέχει ένα σύνολο από αφηρημένες μεθόδους που ορίζουν μία
συμπεριφορά, την οποία συμπεριφορά αποκτούν όσες κλάσεις υλοποιήσουν
τη συγκεκριμένη Διεπαφή (υλοποιώντας αυτές τις αφηρημένες μεθόδους).
• Η διεπαφή είναι μια έννοια ειδικής κλάσης, παρόμοιας με την αφηρημένη
κλάση, που μπορεί να περιέχει μόνο static σταθερές και αφηρημένες
μεθόδους (μόνο τις υπογραφές των μεθόδων, χωρίς υλοποίηση/σώμα).
• Οι διεπαφές μεταγλωττίζονται σε ξεχωριστά bytecode αρχεία (.class) όπως
και οι κανονικές κλάσεις.
• Όπως και στις αφηρημένες κλάσεις δεν μπορούμε να ορίσουμε αντικείμενα
της διεπαφής με τον τελεστή new.
• Μια κλάση μπορεί να υλοποιεί πολλές διεπαφές.
Διεπαφές (Interfaces)
• Δεν περιέχει πεδία, δομητές και στατικές μεθόδους.
• Το σύνολο των μεθόδων πρέπει να υλοποιηθεί από άλλη κλάση/σεις.
• Όλες οι μεταβλητές πρέπει να είναι public, static και final (άμεσα
ή έμμεσα).Οι μέθοδοι public.
• Μια διεπαφή ορίζεται χρησιμοποιώντας την λέξη κλειδί - interface αντί
της δεσμευμένης λέξης class.
Σύνταξη:
public interface <interface name>
{
Δηλώσεις Σταθερών <constant declarations>;
Υπογραφές Μεθόδων <method signatures>;
}
Διεπαφές (Interfaces)
• Μια κλάση που υλοποιεί τη διεπαφή έχει στην επικεφαλίδα της τη
δεσμευμένη λέξη implements και περιλαμβάνει τις μεθόδους με τον
κώδικα που υλοποιεί την λειτουργικότητά τους. Η διεπαφή ‘προδιαγράφει’
τις μεθόδους με την υπογραφή τους (όνομα μεθόδου, τύπος παραμέτρων).
class <ClassName> implements <InterfaceName> { ...}
// συνδυασμός κληρονομικότητας και υλοποίηση Διεπαφής
class <ClassName> extends <SuperClass> implements <InterfaceN-1,
<InterfaceN-2, {...}
// σαν πολλαπλή κληρονομικότητα
• Οι διεπαφές μπορούν να επεκτείνουν | κληρονομούν(extends) άλλες
διεπαφές.
Διεπαφές (Interfaces)
• Μια κλάση μπορεί να επεκτείνει (extends) μόνον μία υπερκλάση (απλή
κληρονομικότητα), όμως μπορεί να υλοποιεί (implements) περισσότερες
από μία διεπαφές (έμμεσα πολλαπλή κληρονομικότητα).
• Οι ιδιότητες του πολυμορφισμού ισχύουν και μεταξύ των διεπαφών και
των κλάσεων που τις υλοποιούν και των υποκλάσεων τους, διότι και εδώ
η υλοποίηση της μεθόδου μιας διεπαφής εξαρτάται από τον τύπο του
αντικειμένου που την καλεί.
• Αν μια κλάση δεν ορίσει όλες τις μεθόδους ενός interface που υλοποιεί
τότε πρέπει να δηλωθεί σαν abstract.
Γιατί χρησιμοποιούμε τις διεπαφές;
• Για να χρησιμοποιούμε την λειτουργικότητα των αντικειμένων και όχι την
υλοποίησή τους (που δεν την γνωρίζουμε).
• Για να εκτελούνται παρόμοιες μέθοδοι από μη συσχετιζόμενες κλάσεις.
• Για να πετύχουμε πολλαπλή κληρονομικότητα.
Διεπαφές (Interfaces)
Η διεπαφή μπορεί να ορίσει σταθερές (που είναι άμεσα ή έμμεσα public, static και final),
που χρησιμοποιούνται απ’ ευθείας με το όνομά τους στις κλάσεις που υλοποιούν την
διεπαφή.
Παράδειγμα:
interface OrismosConstants {
double pi=3.14;
int syntelestis_FPA=25; }
class TestConstants implements OrismosConstants {
public static final int CONST = 18;
public static void main(String args[])
{ System.out.println("Stathera pi tis diepafis= "+pi);
System.out.println("Stathera syntelestis_FPA tis diepafis=
"+syntelestis_FPA);
System.out.println("Stathera tis klasis= "+CONST);}}
Διεπαφές (Interfaces)
Υλοποίηση μεθόδων της διεπαφής (κλασική χρήση), σε κλάση που υλοποιεί την διεπαφή.
Παράδειγμα:
interface MyDemoInterface{
public void method1(); public
void method2(); }
class Aclass implements MyDemoInterface{
public void method1() {
System.out.println("Ylopoiisi tis method1() stin Aclass"); }
public void method2() {
System.out.println("Ylopoiisi tis method2() stin Aclass"); }
public static void main(String arg[]){
MyDemoInterface obj = new Aclass(); obj.
method1();
obj. method2(); } }
Διεπαφές (Interfaces)
Κληρονομικότητα διεπαφής:
Μια διεπαφή μπορεί να κληρονομεί (extends) άλλη διεπαφή όπως μια κλάση
κληρονομεί μια άλλη κλάση. Η child-διεπαφή κληρονομεί τις σταθερές και
μεθόδους της parent-διεπαφής.
Προσοχή στην υλοποίηση των μεθόδων από την κληρονομικότητα των διεπαφών
Στο παρακάτω παράδειγμα, ορίζονται υποχρεωτικά και οι δύο μέθοδοι στην κλάση
Demo, που ενώ υλοποιεί μόνο την διεπαφή Diepafi2 (...θα έπρεπε να ορίσει μόνο
την method2()), πρέπει να ορίσει και την method1() που κληρονομεί από την
Diepafi1.
Διεπαφές (Interfaces)
Παράδειγμα:
interface Diepafi1{
public void method1();}
interface Diepafi2 extends Diepafi1 {
public void method2();}
class Demo implements Diepafi2{
public void method1(){
System.out.println("Ylopoiisi tis method1() tis Diepafi1");}
public void method2(){
System.out.println("Ylopoiisi tis method2() tis Diepafi2");}}
class TestInterface2 {
public static void main(String args[]) {
Demo obj = new Demo(); obj. method1();
obj. method2(); }}
Διεπαφές (Interfaces)
Η διεπαφή Shape ορίζει την μέθοδο draw() που θα υλοποιηθεί στις δύο κλάσεις Circle και
Rectangle που υλοποιούν την διεπαφή. Δες την κλάση ShapeConstruction που υλοποιεί το
πρότυπο (pattern) Factory.
interface Shape
{public void draw();}
class Circle implements Shape
{ public void draw()
{System.out.println("H Draw() gia ton Kyklo");}}
class Rectangle implements Shape
{ public void draw()
{System.out.println("H Draw() gia to Parallilogrammo");}}
class ShapeConstruction {
public Shape getShape(String s){
if (s.equals("Circle")){return new Circle();}
if (s.equals("Rectangle")){return new Rectangle();}
return null; }}
Διεπαφές (Interfaces)
class TestInterfaces {
public static void main(String args[]) {
ShapeConstruction sc=new ShapeConstruction();
Shape sh1=sc.getShape("Circle");//το sh1 θα οριστεί αντικείμενο circle
sh1.draw();
Shape sh2=sc.getShape("Rectangle");//το sh2 θα οριστεί αντ. rectangle
sh2.draw();
}
}
Συνέχεια:
Διεπαφές (Interfaces)
Χαρακτηριστικό Απλή
κλάση
Αφηρημένη
κλάση
Διεπαφή
Μπορούν να δημιουργηθούν αντικείμενα; Ναι Όχι Όχι
Μπορούν να οριστούν πεδία και συγκεκριμένες
μέθοδοι;
Ναι Ναι Όχι
Μπορούν να οριστούν σταθερές; Ναι Ναι Ναι
Μια κλάση μπορεί να επεκτείνει (extends): 0 ή 1 0 ή 1 0
Μια κλάση μπορεί να υλοποιήσει (implements): 0 0 1..*
Μπορούν να οριστούν αφηρημένες μέθοδοι; Όχι Ναι Ναι
Μπορούν να δηλωθούν μεταβλητές αυτών των
τύπων;
Ναι Ναι Ναι
Swing (GUI Programming)
• Το Swing είναι μία βιβλιοθήκη της Java η οποία παρέχει τις κλάσεις για την
δημιουργία αλληλεπιδραστικών γραφικών περιβαλλόντων.
• Τα GUIs δημιουργούνται συνδυάζοντας διάφορα επιμέρους συστατικά
όπως:
• Πλαίσια: Είναι παράθυρα με τίτλο, μενού, κουμπιά ελαχιστοποίησης και
μεγιστοποίησης.
• Υποδοχείς: Στοιχεία τα οποία μπορεί να περιέχουν και άλλα συστατικά.
• Κουμπιά: Περιοχές οι οποίες είναι συσχετισμένες με μία ενέργεια και τις
οποίες ο χρήστης μπορεί να εκτελέσει κάνοντας κλικ με το ποντίκι.
• Πεδία κειμένου: Περιοχές στις οποίες ο χρήστης μπορεί να εισάγει κείμενο.
• Μέσα σε αυτήν την βιβλιοθήκη υπάρχει η κλάση JFrame με εκατοντάδες
δυνατότητες και μεθόδους.
Swing (Classes)
Swing (Components)
• Η κλάση Component είναι μία αφηρημένη κλάση που περιέχει ένα σύνολο
μεθόδων για την διαχείριση των διαφόρων συστατικών ενός GUI. Τα
συστατικά που χρησιμοποιούνται αποτελούν υποκλάσεις της Component και
κληρονομούν τις μεθόδους της. Ενδεικτικές μέθοδοι της Component είναι:
• setLocation(int x, int y): Ορίζει την θέση ενός συστατικού με συντεταγμένες
τις τιμές x και y σε pixels. Η θέση (0,0) βρίσκεται στην πάνω αριστερή γωνία
της οθόνης.
• setSize(int width, int height): Ορίζει το μέγεθος του συστατικού σε pixels.
• setBounds(int x, int y, int width, int height) : Ορίζει την θέση του συστατικού
(x και y) και το μέγεθός του (width και height) σε pixels.
• setFont(Font f) : Ορίζει τη μορφή της γραμματοσειράς που θα περιέχει το
συστατικό.
• setBackground(Color c) : Ορίζει το χρώμα του παρασκηνίου του
συστατικού.
• setVisible(boolean isVisible) : Καθορίζει εάν το συγκεκριμένο συστατικό θα
είναι ορατό ή αόρατο.
• addKeyListener(KeyListener kl) : Προσθέτει έναν ακροατή για συμβάντα
πληκτρολογίου.
• addActionListener(ActionListener al) : Προσθέτει έναν ακροατή για
συμβάντα ενέργειας.
Swing (Frames - Πλαίσια/Υποδοχείς)
• Ο υποδοχέας είναι ένα αντικείμενο της κλάσης Container.
• Μας παρέχει την δυνατότητα να προσθέσουμε άλλα
συστατικά σε ένα υποδοχέα, δημιουργώντας σύνθετα GUI.
• Κάθε γραφική διεπαφή του Swing πρέπει να περιέχει
τουλάχιστον ένα βασικό υποδοχέα. Ένας από τους
βασικούς υποδοχείς είναι τα πλαίσια.
• Τα πλαίσια είναι παράθυρα που εμφανίζονται στην
επιφάνεια εργασίας του χρήστη και περιλαμβάνουν τίτλο,
γραμμή μενού, κουμπιά αλλαγής μεγέθους και κλεισίματος.
• Η κλάση JFrame είναι η συνηθέστερη για την κατασκευή
πλαισίων.
Swing (Frames - Πλαίσια/Υποδοχείς)
package simpleFrame;
import javax.swing.*;
public class SimpleFrame extends JFrame {
public static void main(String[] args) {
JFrame frame = new JFrame ("My First Frame");
frame.setBounds(300,300,400,200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Swing (JComponent - Συστατικά)
• Συστατικά είναι τα μέρη από τα οποία αποτελείται ένα GUI. Ένα
σύνολο συστατικών τοποθετείται μέσα σε έναν υποδοχέα και
δημιουργείται μια ολοκληρωμένη γραφική διεπαφή.
• Η κλάση JButton χρησιμοποιείται για την δημιουργία κουμπιών τα
οποία ο χρήστης μπορεί να ενεργοποιήσει με το ποντίκι.
• Για την δημιουργία ενός αντικειμένου JButton χρησιμοποιούνται οι
παρακάτω κατασκευαστές:
 JButton()
 JButton(String text)
 JButton(Icon ic)
 JButton(String text,Icon ic)
Swing (JComponent - Συστατικά)
• H κλάση JLabel χρησιμοποιείται για την δημιουργία
ετικετών που μπορούν να περιέχουν κείμενο ή/και
εικόνα.
• Για την δημιουργία μιας ετικέτας χρησιμοποιούνται από
την κλάση Jlabel οι παρακάτω κατασκευαστές:
 JLabel()
 JLabel(String text)
 JLabel(Icon ic)
 JLabel(String text,Icon ic)
Swing (JComponent - Συστατικά)
• Η κλάση JTextField χρησιμοποιείται για την δημιουργία
ενός πεδίου κειμένου.
•
Παρόμοια είναι και η κλάση JTextArea η οποία όμως
χρησιμοποιείται για την εισαγωγή μεγαλύτερων κειμένων.
• Για την δημιουργία JTextField χρησιμοποιούνται οι
παρακάτω κατασκευαστές:
 JTextField()
 JTextField(String text)
 JTextField(int numOfColumns)
 JTextField(String text, int numOfColumns)
Swing (JComponent - Παράδειγμα)
package simpleFrame;
import javax.swing.*;
public class SimpleFrame extends JFrame {
public static void main(String[] args) {
JFrame frame = new JFrame ("My First GUI");
frame.setSize(400,400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setLayout(null);
JLabel label = new JLabel("JLabel");
JTextField text = new JTextField();
JButton button = new JButton("OK");
label.setBounds(10,10,100,20);
text.setBounds(100, 10, 100, 20);
button.setBounds(100,50,60,20);
frame.add(label);
frame.add(text);
frame.add(button);
}
}
Swing (Components)

More Related Content

PDF
Java_09012024.pdf
PPTX
Maria Ioanna Sifaki
PDF
Python tutorial by example
PDF
Fortran notes panepistimio_kritis
PDF
Lesson 10 - Inheritance - polymorphism.pdf
PDF
UML
PPTX
DynaCraft: a super-strongly typed programming language
PDF
ΘΕΜΑΤΑ ΠΑΝΕΛΛΗΝΙΩΝ 2025 - ΠΛΗΡΟΦΟΡΙΚΗ.pdf
Java_09012024.pdf
Maria Ioanna Sifaki
Python tutorial by example
Fortran notes panepistimio_kritis
Lesson 10 - Inheritance - polymorphism.pdf
UML
DynaCraft: a super-strongly typed programming language
ΘΕΜΑΤΑ ΠΑΝΕΛΛΗΝΙΩΝ 2025 - ΠΛΗΡΟΦΟΡΙΚΗ.pdf

Similar to Java_16012024.pdf (20)

PDF
Ανάπτυξη Εφαρμογών σε Προγραμματιστικό Περιβάλλον - Ταξινόμηση με υποπρόγραμμα
PDF
Cs b gym_worksheets_20160527
PPT
ΑΕΠΠ ΚΕΦ 9
PDF
Papatzelos Spiridon
PPTX
Source Code Bug Detection and Repair using Deep Learning Techniques
PDF
Βελτίωση Αυτοματοποιημένης Ανάθεσης Εργασιών Λογισμικού με χρήση Commits σε Δ...
PDF
Cs c gym_worksheets_20160622
PPTX
Ioannis Iakovidis
PPTX
Νούτσος Αντώνης 6992
PPT
Σχεδίαση και υλοποίηση εφαρμογής Βάσεων Δεδομένων για τη διαχείριση βιβλιοθήκης
PDF
Cs a gym_worksheets_20160526
PDF
βάσεις δεδομένων κεφ2
PDF
Η ΓΛΩΣΣΑ C++ - ΜΑΘΗΜΑ 2 - ΕΙΣΑΓΩΓΗ ΣΤΙΣ ΚΛΑΣΕΙΣ
PPTX
Pliroforiki (software) socrates fotiou
PPTX
Μαρίνα Γέραλη
PDF
Lectures 1 6
PPTX
Kagiafas Nikolaos Thesis Presentation
PPTX
Applying Data Mining Techniques on Software Repositories to Extract Design an...
PPTX
Εφαρμογή Τεχνικών Εξόρυξης Δεδομένων σε Αποθήκες Λογισμικού με σκοπό την Εξα...
PDF
Η ΓΛΩΣΣΑ C++ - ΜΑΘΗΜΑ 4 - ΚΛΑΣΕΙΣ ΚΑΙ ΑΝΑΦΟΡΕΣ
Ανάπτυξη Εφαρμογών σε Προγραμματιστικό Περιβάλλον - Ταξινόμηση με υποπρόγραμμα
Cs b gym_worksheets_20160527
ΑΕΠΠ ΚΕΦ 9
Papatzelos Spiridon
Source Code Bug Detection and Repair using Deep Learning Techniques
Βελτίωση Αυτοματοποιημένης Ανάθεσης Εργασιών Λογισμικού με χρήση Commits σε Δ...
Cs c gym_worksheets_20160622
Ioannis Iakovidis
Νούτσος Αντώνης 6992
Σχεδίαση και υλοποίηση εφαρμογής Βάσεων Δεδομένων για τη διαχείριση βιβλιοθήκης
Cs a gym_worksheets_20160526
βάσεις δεδομένων κεφ2
Η ΓΛΩΣΣΑ C++ - ΜΑΘΗΜΑ 2 - ΕΙΣΑΓΩΓΗ ΣΤΙΣ ΚΛΑΣΕΙΣ
Pliroforiki (software) socrates fotiou
Μαρίνα Γέραλη
Lectures 1 6
Kagiafas Nikolaos Thesis Presentation
Applying Data Mining Techniques on Software Repositories to Extract Design an...
Εφαρμογή Τεχνικών Εξόρυξης Δεδομένων σε Αποθήκες Λογισμικού με σκοπό την Εξα...
Η ΓΛΩΣΣΑ C++ - ΜΑΘΗΜΑ 4 - ΚΛΑΣΕΙΣ ΚΑΙ ΑΝΑΦΟΡΕΣ

Java_16012024.pdf

  • 1. Άσκηση Μισθοδοσίας/Employee (υλοποίηση κληρονομικότητας) Η μισθοδοσία των υπαλλήλων μιας εταιρείας περιλαμβάνει 2 κατηγορίες υπαλλήλων: 1. Tους Διοικητικούς 2. Tους Τεχνικούς. Για τις 2 κατηγορίες υπάρχουν δύο τύποι μισθοδοσίας • 0=Μισθωτός • 1=Ωρομίσθιος. Ο βασικός μισθός για τους Διοικητικούς είναι 1200 Ευρώ και για τους Τεχνικούς 800 Ευρώ, ενώ και οι 2 κατηγορίες μπορούν να λάβουν και ένα bonus (X)-Ευρώ. Ο μισθός υπολογίζεται με την σχέση: Μισθός = Βασικός + Βonus, για τους μισθωτούς και για τους ωρομίσθιους με τη σχέση: Μισθός = Ώρες Εργασίας * Τιμή Ώρας (όπου για τον Διοικητικό είναι 12 Ευρώ την ώρα, και για τον Τεχνικό 10 Ευρώ/ώρα). Η υπερκλάση: Employee, θα ορίζει 4 χαρακτηριστικά που είναι κοινά και για τις δύο κατηγορίες (1) Name, (2) Bonus, (3) Hours (για τους ωρομίσθιους) και (4) Τύπος Υπάλληλου (0=Διοικητικός, 1=Τεχνικός) θα υλοποιεί τις μεθόδους 1. getPayType() που επιστρέφει τα μηνύματα ‘Μισθός’ ή ‘Με την Ώρα’ ανάλογα του τύπου μισθοδοσίας 2. getEmpType() που επιστρέφει το μήνυμα “Employee type=Τύπος εργαζομένου” 3. calcSalary(), που υπολογίζει τον μισθό του Employee. Οι υποκλάσεις: Administrator και Technical θα κληρονομούν τα 4-χαρακτηριστικά και την μέθοδο getPayType() από την υπερκλάση, ενώ θα υπερβαίνουν (override) τις μεθόδους getEmpType() και calcSalary(). Χρησιμοποιήστε μια βοηθητική κλάση την Company στην οποία αρχικοποιείται ένας πίνακας 4- αντικειμένων όλων των τύπων και επιπλέον 2 μεθόδους (α) setEmployee(), που εισάγει τα αντικείμενα στον πίνακα και (β) printAll() που εμφανίζει τα στοιχεία του κάθε υπάλληλου και τον μισθό του.
  • 2. Άσκηση Μισθοδοσίας/Employee (υλοποίηση κληρονομικότητας) Η μισθοδοσία των υπαλλήλων μιας εταιρείας περιλαμβάνει 2 κατηγορίες υπαλλήλων: 1. Tους Διοικητικούς 2. Tους Τεχνικούς. Για τις 2 κατηγορίες υπάρχουν δύο τύποι μισθοδοσίας • 0=Μισθωτός • 1=Ωρομίσθιος. Ο βασικός μισθός για τους Διοικητικούς είναι 1200 Ευρώ και για τους Τεχνικούς 800 Ευρώ, ενώ και οι 2 κατηγορίες μπορούν να λάβουν και ένα bonus (X)-Ευρώ. Ο μισθός υπολογίζεται με την σχέση: Μισθός = Βασικός + Βonus, για τους μισθωτούς και για τους ωρομίσθιους με τη σχέση: Μισθός = Ώρες Εργασίας * Τιμή Ώρας (όπου για τον Διοικητικό είναι 12 Ευρώ την ώρα, και για τον Τεχνικό 10 Ευρώ/ώρα). Η υπερκλάση: Employee, θα ορίζει 4 χαρακτηριστικά που είναι κοινά και για τις δύο κατηγορίες (1) Name, (2) Bonus, (3) Hours (για τους ωρομίσθιους) και (4) Τύπος Υπάλληλου (0=Διοικητικός, 1=Τεχνικός) θα υλοποιεί τις μεθόδους 1. getPayType() που επιστρέφει τα μηνύματα ‘Μισθός’ ή ‘Με την Ώρα’ ανάλογα του τύπου μισθοδοσίας 2. getEmpType() που επιστρέφει το μήνυμα “Employee type=Τύπος εργαζομένου” 3. calcSalary(), που υπολογίζει τον μισθό του Employee. Οι υποκλάσεις: Administrator και Technical θα κληρονομούν τα 4-χαρακτηριστικά και την μέθοδο getPayType() από την υπερκλάση, ενώ θα υπερβαίνουν (override) τις μεθόδους getEmpType() και calcSalary(). Χρησιμοποιήστε μια βοηθητική κλάση την Company στην οποία αρχικοποιείται ένας πίνακας 4- αντικειμένων όλων των τύπων και επιπλέον 2 μεθόδους (α) setEmployee(), που εισάγει τα αντικείμενα στον πίνακα και (β) printAll() που εμφανίζει τα στοιχεία του κάθε υπάλληλου και τον μισθό του.
  • 3. Απόκρυψη Πεδίων (Hiding Fields) • Στην υποκλάση ένα πεδίο με το ίδιο όνομα πεδίου της υπερκλάσης ‘κρύβει’ το πεδίο της υπερκλάσης ακόμη και αν είναι διαφορετικού τύπου. Στην υποκλάση, για να έχουμε πρόσβαση στο πεδίο της υπερκλάσης χρησιμοποιούμε τη super. • Η απόκρυψη πεδίων κάνει δύσκολη την αναγνωσιμότητα του κώδικα, για αυτό πρέπει να την αποφεύγουμε. • Το πεδίο στην υποκλάση με το ίδιο όνομα της υποκλάσης είναι ένα νέο πεδίο, το πεδίο της υπερκλάσης είναι κρυμμένο και δεν μπορούμε να το υπερβούμε. Δεν υπάρχει υπέρβαση πεδίων, όπως γίνεται με τις μεθόδους. • Πρόσβαση σε κρυμμένα πεδία έχουμε με: (α) χρήση αναφοράς υπερκλάσης (δες το παράδειγμα) (β) χρήση casting: System.out.println(((Super)c1).s);
  • 4. Απόκρυψη Πεδίων (Hiding Fields) Παράδειγμα class SuperClass { String f = "Yperklasi";} class SubClass extends SuperClass {String f = "Ypoklasi";} public class YpervasiPediou { public static void main(String[] args) { SubClass p1 = new SubClass(); System.out.println(p1.f); SuperClass p2 = new SubClass(); //αναφορά υπερκλάσης System.out.println(p2.f); System.out.println(((SuperClass)p1).f); //casting } }
  • 5. Πολυμορφισμός (Polymorphism) Χρησιμοποιούμε Πολυμορφισμό υποκλάσης για να εκτελέσουμε διαφορετικές μορφές της ίδιας μεθόδου. Πολυμορφισμό έχουμε: • Όταν ο αποστολέας ενός μηνύματος δεν χρειάζεται να γνωρίζει την κλάση του παραλήπτη (στιγμιότυπου). • Όταν μια λειτουργία μπορεί να υλοποιηθεί με το ίδιο όνομα αλλά με διαφορετικό περιεχόμενο σε διαφορετικές κλάσεις (τρόπο λειτουργίας). • Στον πολυμορφισμό μια μεταβλητή της υπερκλάσης αναφέρεται σε ένα αντικείμενο της υποκλάσης. Έτσι παρέχεται η δυνατότητα σε μια μεταβλητή αναφοράς αντικειμένου να αλλάζει συμπεριφορά (εκτελεί διαφορετικές μεθόδους) ανάλογα με το αντικείμενο στο οποίο αναφέρεται την κάθε φορά.
  • 6. Πολυμορφισμός (Polymorphism) • Ο πολυμορφισμός αναφέρεται στη δυνατότητα να χειριζόμαστε αντικείμενα που ανήκουν στην ίδια ιεραρχία κλάσεων, σαν να ήταν αντικείμενα της υπερκλάσης. Για την επίτευξη πολυμορφικής συμπεριφοράς απαιτείται μία ιεραρχία κλάσεων και υπερκαλυπτόμενες μέθοδοι.
  • 7. Πολυμορφισμός (Polymorphism) class Animal { void sound() {System.out.println("Animal Sound");} } class Cat extends Animal { void sound() {// Overriding System.out.println("Cat Sound: miaou"); } } class Dog extends Animal { void sound() {// Overriding System.out.println("Dog Sound: wooof");} } class testPoly { public static void main(String[] args) { Animal animal = new Animal(); animal.sound(); Cat cat = new Cat(); cat.sound(); Dog dog = new Dog(); dog.sound(); System.out.println(); System.out.println("Poly-1: Animal c = new Cat();"); System.out.println(" "); Animal c = new Cat(); //ότι η κλάση και όχι η αναφορά // η cat sound() c.sound(); System.out.println(); System.out.println("Poly-2: Animal c = new Dog();"); System.out.println(" "); Animal d = new Dog(); //ότι η κλάση και όχι η αναφορά //dog sound() d.sound(); } }
  • 8. Πολυμορφισμός Yποκλάσης (Upcasting - Downcasting) Animal Mammal Reptile Cat Dog Object Upcasting downcasting • Casting: Η ανάθεση του αντικειμένου ενός τύπου σε αναφορά άλλου τύπου. • Επιτρέπονται castings μόνο μεταξύ αντικειμένων σε μια ιεραρχία κληρονομικότητας. • Upcasting: Η ανάθεση ενός αντικειμένου της υποκλάσης σε αναφορά της υπερκλάσης. Δεν χρειάζεται κάποιο προσδιοριστικό, γιατί η υποκλάση είναι μια εξειδίκευση της υπερκλάσης. π.χ. Animal c = new Cat(); //late binding • Δεν αλλάζει το αντικείμενο Cat αλλά το χειρίζεσαι σαν οποιοδήποτε άλλο αντικείμενο της Animal. Κρύβεις τις ιδιότητες της Cat, μέχρι να το κάνεις ξανά downcast σε Cat. Cat c = new Cat(); System.out.println(c); Mammal m = c; //Cat@a90653 // upcasting System.out.println(m); //Cat@a90653 Το αντικείμενο Cat δεν άλλαξε μετά το upcasting, αλλά μετονομάστικε σε Mammal. Όμως δεν γίνεται cast σε Dog. Οι ορισμοί (1) Mammal m=new Cat(); και (2) Mammal m=(Mammal)new Cat(); Είναι ισοδύναμοι. Ο (2) δεν απαιτείται.
  • 9. Πολυμορφισμός Yποκλάσης (Upcasting - Downcasting) • Το downcasting (από την υπερκλάση στην υποκλάση) δεν γίνεται αυτόματα, αλλά ρητά προγραμματιστικά (τον τύπο μέσα σε αγκύλες). Cat c1 = new Cat(); Animal a = c1; Cat c2 = (Cat) a; //αυτόματο upcasting σε Animal // downcasting σε αντικείμενο τύπου Cat • Πριν από κάποιο downcasting μπορούμε να ελέγξουμε τον τύπο του αντικειμένου με την instanceof. Π.χ. Cat c1 = new Cat(); Animal a = c1; //upcasting σε Animal // έλεγχος αν το Animal είναι ένα αντικείμενο Cat if(a instanceof Cat) { System.out.println(“Einai antikeimeno Cat”); Cat c2 = (Cat)a; //ασφαλές downcasting }
  • 10. Πολυμορφισμός Yποκλάσης (Upcasting - Downcasting) Upcasting μέσω της κλήσης μεθόδου public static void walk(Animal a) { System.out.println(“Animal walk "+a); } : : Cat c = new Cat(); Dog d = new Dog(); walk(c); walk(d); // αυτόματο upcast σε Animal // αυτόματο upcast σε Animal Downcasting μέσω της κλήσης μεθόδου class Animal { } class Dog extends Animal { static void method(Animal a) { Dog d=(Dog)a; //downcasting System.out.println("ok to downcasting egine");} public static void main (String [] args) { Animal a=new Dog(); Dog.method(a); }}
  • 11. Πολυμορφισμός Yποκλάσης (Upcasting - Downcasting) class A { public A() { System.out.println("Domitis A");} public String toString(){return "toString() klasis A"; }} class B extends A { public B() { super(); System.out.println("Domitis B");} @Override public String toString() { return "Ypervasi-toString() klasis B";}} class C extends B { public C() { super(); System.out.println("Domitis C");} @Override public String toString() { return "Ypervasi-toString() klasis C";}} public class TestCasting { public static void main(String[] args) { A a1 = new C(); // ok, upcast System.out.println(a1); //ekteleitai toString() tis C-klasis B b1 = (B)a1; System.out.println(b1); C c1 = (C)b1; System.out.println(c1); A a2 = new B(); System.out.println(a2); B b2 = (B)a2; System.out.println(b2); // ok, downcast // -->>--metonomasia tou // antikeimenou se B1 // ok, downcast //-->>--metonomasia tou // antikeimenou se C1 // ok, upcast //ekteleitai toString() tis B-klasis // ok, downcast //-->>--metonomasia tou //antikeimenou se b2 } }
  • 12. Αφηρημένες Κλάσεις (abstract classes) Αφηρημένοι Τύποι Δεδομένων (Abstract Data Types – ADT): Αφηρημένες κλάσεις και Διεπαφές/Διασυνδέσεις Αφηρημένη κλάση (abstract class) είναι μια κλάση που αντιπροσωπεύει μια ευρεία κατηγορία τύπων και ορίζεται μόνο για να κληρονομηθεί (επεκταθεί) από θυγατρικές υποκλάσεις (π.χ. liquid, people, mammal, employee, κλπ.) Σύνταξη (η δεσμευμένη λέξη abstract): (1) κλάση: <visibility> abstract class <name> { } (2) μέθοδος: <visibility> abstract <type> <name> ([parameters]); Κανόνες και Συνθήκες: • Δεν μπορούμε να δημιουργήσουμε αντικείμενα μιας αφηρημένης κλάσης (τελεστής new), αλλά μπορούμε να ορίσουμε δομητές (και να έχουμε πρόσβαση από τους δομητές των υποκλάσεων). • Μια αφηρημένη μέθοδος δεν μπορεί να υπάρχει σε μια μη αφηρημένη κλάση. Αν μια υποκλάση δεν υλοποιεί όλες τις αφηρημένες μεθόδους, τότε πρέπει να δηλωθεί abstract.
  • 13. Αφηρημένες Κλάσεις (abstract classes) • Η αφηρημένη κλάση ορίζει απλώς ένα "συμβόλαιο" το οποίο θα πρέπει να ακολουθούν οι υποκλάσεις της όσον αφορά τις υπογραφές των μεθόδων τους. • Οι αφηρημένες μέθοδοί της είναι απλώς ένας ορισμός της υπογραφής τους και εναπόκειται στις υποκλάσεις να τις ορίσουν και υλοποιήσουν (συμβόλαιο). • Δηλαδή, η αφηρημένη μέθοδος δεν έχει σώμα και τελειώνει με το (;) • Οι αφηρημένες μέθοδοι πρέπει να είναι public (ή protected), όχι private. • Ο όρος abstract δεν μπορεί να χρησιμοποιηθεί σε στατικές μεθόδους ή δομητές.
  • 14. Αφηρημένες Κλάσεις (abstract classes) • Μία αφηρημένη κλάση μπορεί να έχει και μη αφηρημένες μεθόδους οι οποίες υλοποιούνται στην ίδια την κλάση (αν και μπορούμε να τις υπερβούμε στις υποκλάσεις). Αν δεν περιέχει καμία abstract μέθοδο λειτουργεί μεν σαν υπερκλάση, ωστόσο δεν μπορούμε να ορίσουμε αντικείμενα της (τελεστής new). • Μια υποκλάση μπορεί να δηλωθεί abstract, ακόμη και αν η υπερκλάση είναι μη abstract. • Μια abstract κλάση μπορεί να χρησιμοποιηθεί σαν τύπος δεδομένων π.χ. Array - αντικειμένων, τότε μπορούμε να χρησιμοποιήσουμε τον τελεστή new. π.χ. People[ ] objs = new People[5]; Μετά γεμίζουμε τον πίνακα με αναφορές αντικειμένων, υποκλάσεων: π.χ. People [0]= new Student(); (πολυμορφική συμπεριφορά)
  • 15. Αφηρημένες Κλάσεις (abstract classes) Παράδειγμα : Δημιουργούμε δύο Shape – αντικείμενα: ένα κύκλο και ένα ορθογώνιο που υλοποιούν τις δύο abstract μεθόδους getArea() και getPerimeter(). abstract class Shape { private String color; private boolean filled; /** Abstract method getArea */ public abstract double getArea(); /** Abstract method getPerimeter */ public abstract double getPerimeter(); } class Circle extends Shape { private double radius; public Circle(double r) {this.radius = r;} public void setRadius(double r) {this.radius = r;} public double getRadius() {return radius;} @Override /** Return area */ public double getArea() {return radius * radius * Math.PI;} public double getDiameter() {return 2 * radius;} @Override /** Return perimeter */ public double getPerimeter() {return 2 * radius * Math.PI;} public void printCircle() { System.out.println("The radius is + radius);} }
  • 16. Αφηρημένες Κλάσεις (abstract classes) class Rectangle extends Shape { private double width; private double height; public Rectangle(double width, double height) { this.width = width; this.height = height;} public double getWidth() {return width;} public void setWidth(double width) {this.width = width;} public double getHeight() {return height;} public void setHeight(double height) {this.height = height;} @Override /** Return area */ public double getArea() {return width * height;} @Override /** Return perimeter */ public double getPerimeter() {return 2 * (width + height);}} class TestShape { public static void main(String[] args) { Shape Object1 = new Circle(8); Shape Object2 = new Rectangle(2, 4); // Display circle displayObject(Object1); // Display rectangle displayObject(Object2); } public static void displayObject( Shape object) { System.out.println("The area is " + object.getArea()); System.out.println("The perimeter is « + object.getPerimeter()); } }
  • 17. Διεπαφές (Interfaces) Η Διεπαφή περιέχει ένα σύνολο από αφηρημένες μεθόδους που ορίζουν μία συμπεριφορά, την οποία συμπεριφορά αποκτούν όσες κλάσεις υλοποιήσουν τη συγκεκριμένη Διεπαφή (υλοποιώντας αυτές τις αφηρημένες μεθόδους). • Η διεπαφή είναι μια έννοια ειδικής κλάσης, παρόμοιας με την αφηρημένη κλάση, που μπορεί να περιέχει μόνο static σταθερές και αφηρημένες μεθόδους (μόνο τις υπογραφές των μεθόδων, χωρίς υλοποίηση/σώμα). • Οι διεπαφές μεταγλωττίζονται σε ξεχωριστά bytecode αρχεία (.class) όπως και οι κανονικές κλάσεις. • Όπως και στις αφηρημένες κλάσεις δεν μπορούμε να ορίσουμε αντικείμενα της διεπαφής με τον τελεστή new. • Μια κλάση μπορεί να υλοποιεί πολλές διεπαφές.
  • 18. Διεπαφές (Interfaces) • Δεν περιέχει πεδία, δομητές και στατικές μεθόδους. • Το σύνολο των μεθόδων πρέπει να υλοποιηθεί από άλλη κλάση/σεις. • Όλες οι μεταβλητές πρέπει να είναι public, static και final (άμεσα ή έμμεσα).Οι μέθοδοι public. • Μια διεπαφή ορίζεται χρησιμοποιώντας την λέξη κλειδί - interface αντί της δεσμευμένης λέξης class. Σύνταξη: public interface <interface name> { Δηλώσεις Σταθερών <constant declarations>; Υπογραφές Μεθόδων <method signatures>; }
  • 19. Διεπαφές (Interfaces) • Μια κλάση που υλοποιεί τη διεπαφή έχει στην επικεφαλίδα της τη δεσμευμένη λέξη implements και περιλαμβάνει τις μεθόδους με τον κώδικα που υλοποιεί την λειτουργικότητά τους. Η διεπαφή ‘προδιαγράφει’ τις μεθόδους με την υπογραφή τους (όνομα μεθόδου, τύπος παραμέτρων). class <ClassName> implements <InterfaceName> { ...} // συνδυασμός κληρονομικότητας και υλοποίηση Διεπαφής class <ClassName> extends <SuperClass> implements <InterfaceN-1, <InterfaceN-2, {...} // σαν πολλαπλή κληρονομικότητα • Οι διεπαφές μπορούν να επεκτείνουν | κληρονομούν(extends) άλλες διεπαφές.
  • 20. Διεπαφές (Interfaces) • Μια κλάση μπορεί να επεκτείνει (extends) μόνον μία υπερκλάση (απλή κληρονομικότητα), όμως μπορεί να υλοποιεί (implements) περισσότερες από μία διεπαφές (έμμεσα πολλαπλή κληρονομικότητα). • Οι ιδιότητες του πολυμορφισμού ισχύουν και μεταξύ των διεπαφών και των κλάσεων που τις υλοποιούν και των υποκλάσεων τους, διότι και εδώ η υλοποίηση της μεθόδου μιας διεπαφής εξαρτάται από τον τύπο του αντικειμένου που την καλεί. • Αν μια κλάση δεν ορίσει όλες τις μεθόδους ενός interface που υλοποιεί τότε πρέπει να δηλωθεί σαν abstract. Γιατί χρησιμοποιούμε τις διεπαφές; • Για να χρησιμοποιούμε την λειτουργικότητα των αντικειμένων και όχι την υλοποίησή τους (που δεν την γνωρίζουμε). • Για να εκτελούνται παρόμοιες μέθοδοι από μη συσχετιζόμενες κλάσεις. • Για να πετύχουμε πολλαπλή κληρονομικότητα.
  • 21. Διεπαφές (Interfaces) Η διεπαφή μπορεί να ορίσει σταθερές (που είναι άμεσα ή έμμεσα public, static και final), που χρησιμοποιούνται απ’ ευθείας με το όνομά τους στις κλάσεις που υλοποιούν την διεπαφή. Παράδειγμα: interface OrismosConstants { double pi=3.14; int syntelestis_FPA=25; } class TestConstants implements OrismosConstants { public static final int CONST = 18; public static void main(String args[]) { System.out.println("Stathera pi tis diepafis= "+pi); System.out.println("Stathera syntelestis_FPA tis diepafis= "+syntelestis_FPA); System.out.println("Stathera tis klasis= "+CONST);}}
  • 22. Διεπαφές (Interfaces) Υλοποίηση μεθόδων της διεπαφής (κλασική χρήση), σε κλάση που υλοποιεί την διεπαφή. Παράδειγμα: interface MyDemoInterface{ public void method1(); public void method2(); } class Aclass implements MyDemoInterface{ public void method1() { System.out.println("Ylopoiisi tis method1() stin Aclass"); } public void method2() { System.out.println("Ylopoiisi tis method2() stin Aclass"); } public static void main(String arg[]){ MyDemoInterface obj = new Aclass(); obj. method1(); obj. method2(); } }
  • 23. Διεπαφές (Interfaces) Κληρονομικότητα διεπαφής: Μια διεπαφή μπορεί να κληρονομεί (extends) άλλη διεπαφή όπως μια κλάση κληρονομεί μια άλλη κλάση. Η child-διεπαφή κληρονομεί τις σταθερές και μεθόδους της parent-διεπαφής. Προσοχή στην υλοποίηση των μεθόδων από την κληρονομικότητα των διεπαφών Στο παρακάτω παράδειγμα, ορίζονται υποχρεωτικά και οι δύο μέθοδοι στην κλάση Demo, που ενώ υλοποιεί μόνο την διεπαφή Diepafi2 (...θα έπρεπε να ορίσει μόνο την method2()), πρέπει να ορίσει και την method1() που κληρονομεί από την Diepafi1.
  • 24. Διεπαφές (Interfaces) Παράδειγμα: interface Diepafi1{ public void method1();} interface Diepafi2 extends Diepafi1 { public void method2();} class Demo implements Diepafi2{ public void method1(){ System.out.println("Ylopoiisi tis method1() tis Diepafi1");} public void method2(){ System.out.println("Ylopoiisi tis method2() tis Diepafi2");}} class TestInterface2 { public static void main(String args[]) { Demo obj = new Demo(); obj. method1(); obj. method2(); }}
  • 25. Διεπαφές (Interfaces) Η διεπαφή Shape ορίζει την μέθοδο draw() που θα υλοποιηθεί στις δύο κλάσεις Circle και Rectangle που υλοποιούν την διεπαφή. Δες την κλάση ShapeConstruction που υλοποιεί το πρότυπο (pattern) Factory. interface Shape {public void draw();} class Circle implements Shape { public void draw() {System.out.println("H Draw() gia ton Kyklo");}} class Rectangle implements Shape { public void draw() {System.out.println("H Draw() gia to Parallilogrammo");}} class ShapeConstruction { public Shape getShape(String s){ if (s.equals("Circle")){return new Circle();} if (s.equals("Rectangle")){return new Rectangle();} return null; }}
  • 26. Διεπαφές (Interfaces) class TestInterfaces { public static void main(String args[]) { ShapeConstruction sc=new ShapeConstruction(); Shape sh1=sc.getShape("Circle");//το sh1 θα οριστεί αντικείμενο circle sh1.draw(); Shape sh2=sc.getShape("Rectangle");//το sh2 θα οριστεί αντ. rectangle sh2.draw(); } } Συνέχεια:
  • 27. Διεπαφές (Interfaces) Χαρακτηριστικό Απλή κλάση Αφηρημένη κλάση Διεπαφή Μπορούν να δημιουργηθούν αντικείμενα; Ναι Όχι Όχι Μπορούν να οριστούν πεδία και συγκεκριμένες μέθοδοι; Ναι Ναι Όχι Μπορούν να οριστούν σταθερές; Ναι Ναι Ναι Μια κλάση μπορεί να επεκτείνει (extends): 0 ή 1 0 ή 1 0 Μια κλάση μπορεί να υλοποιήσει (implements): 0 0 1..* Μπορούν να οριστούν αφηρημένες μέθοδοι; Όχι Ναι Ναι Μπορούν να δηλωθούν μεταβλητές αυτών των τύπων; Ναι Ναι Ναι
  • 28. Swing (GUI Programming) • Το Swing είναι μία βιβλιοθήκη της Java η οποία παρέχει τις κλάσεις για την δημιουργία αλληλεπιδραστικών γραφικών περιβαλλόντων. • Τα GUIs δημιουργούνται συνδυάζοντας διάφορα επιμέρους συστατικά όπως: • Πλαίσια: Είναι παράθυρα με τίτλο, μενού, κουμπιά ελαχιστοποίησης και μεγιστοποίησης. • Υποδοχείς: Στοιχεία τα οποία μπορεί να περιέχουν και άλλα συστατικά. • Κουμπιά: Περιοχές οι οποίες είναι συσχετισμένες με μία ενέργεια και τις οποίες ο χρήστης μπορεί να εκτελέσει κάνοντας κλικ με το ποντίκι. • Πεδία κειμένου: Περιοχές στις οποίες ο χρήστης μπορεί να εισάγει κείμενο. • Μέσα σε αυτήν την βιβλιοθήκη υπάρχει η κλάση JFrame με εκατοντάδες δυνατότητες και μεθόδους.
  • 30. Swing (Components) • Η κλάση Component είναι μία αφηρημένη κλάση που περιέχει ένα σύνολο μεθόδων για την διαχείριση των διαφόρων συστατικών ενός GUI. Τα συστατικά που χρησιμοποιούνται αποτελούν υποκλάσεις της Component και κληρονομούν τις μεθόδους της. Ενδεικτικές μέθοδοι της Component είναι: • setLocation(int x, int y): Ορίζει την θέση ενός συστατικού με συντεταγμένες τις τιμές x και y σε pixels. Η θέση (0,0) βρίσκεται στην πάνω αριστερή γωνία της οθόνης. • setSize(int width, int height): Ορίζει το μέγεθος του συστατικού σε pixels. • setBounds(int x, int y, int width, int height) : Ορίζει την θέση του συστατικού (x και y) και το μέγεθός του (width και height) σε pixels. • setFont(Font f) : Ορίζει τη μορφή της γραμματοσειράς που θα περιέχει το συστατικό. • setBackground(Color c) : Ορίζει το χρώμα του παρασκηνίου του συστατικού. • setVisible(boolean isVisible) : Καθορίζει εάν το συγκεκριμένο συστατικό θα είναι ορατό ή αόρατο. • addKeyListener(KeyListener kl) : Προσθέτει έναν ακροατή για συμβάντα πληκτρολογίου. • addActionListener(ActionListener al) : Προσθέτει έναν ακροατή για συμβάντα ενέργειας.
  • 31. Swing (Frames - Πλαίσια/Υποδοχείς) • Ο υποδοχέας είναι ένα αντικείμενο της κλάσης Container. • Μας παρέχει την δυνατότητα να προσθέσουμε άλλα συστατικά σε ένα υποδοχέα, δημιουργώντας σύνθετα GUI. • Κάθε γραφική διεπαφή του Swing πρέπει να περιέχει τουλάχιστον ένα βασικό υποδοχέα. Ένας από τους βασικούς υποδοχείς είναι τα πλαίσια. • Τα πλαίσια είναι παράθυρα που εμφανίζονται στην επιφάνεια εργασίας του χρήστη και περιλαμβάνουν τίτλο, γραμμή μενού, κουμπιά αλλαγής μεγέθους και κλεισίματος. • Η κλάση JFrame είναι η συνηθέστερη για την κατασκευή πλαισίων.
  • 32. Swing (Frames - Πλαίσια/Υποδοχείς) package simpleFrame; import javax.swing.*; public class SimpleFrame extends JFrame { public static void main(String[] args) { JFrame frame = new JFrame ("My First Frame"); frame.setBounds(300,300,400,200); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }
  • 33. Swing (JComponent - Συστατικά) • Συστατικά είναι τα μέρη από τα οποία αποτελείται ένα GUI. Ένα σύνολο συστατικών τοποθετείται μέσα σε έναν υποδοχέα και δημιουργείται μια ολοκληρωμένη γραφική διεπαφή. • Η κλάση JButton χρησιμοποιείται για την δημιουργία κουμπιών τα οποία ο χρήστης μπορεί να ενεργοποιήσει με το ποντίκι. • Για την δημιουργία ενός αντικειμένου JButton χρησιμοποιούνται οι παρακάτω κατασκευαστές:  JButton()  JButton(String text)  JButton(Icon ic)  JButton(String text,Icon ic)
  • 34. Swing (JComponent - Συστατικά) • H κλάση JLabel χρησιμοποιείται για την δημιουργία ετικετών που μπορούν να περιέχουν κείμενο ή/και εικόνα. • Για την δημιουργία μιας ετικέτας χρησιμοποιούνται από την κλάση Jlabel οι παρακάτω κατασκευαστές:  JLabel()  JLabel(String text)  JLabel(Icon ic)  JLabel(String text,Icon ic)
  • 35. Swing (JComponent - Συστατικά) • Η κλάση JTextField χρησιμοποιείται για την δημιουργία ενός πεδίου κειμένου. • Παρόμοια είναι και η κλάση JTextArea η οποία όμως χρησιμοποιείται για την εισαγωγή μεγαλύτερων κειμένων. • Για την δημιουργία JTextField χρησιμοποιούνται οι παρακάτω κατασκευαστές:  JTextField()  JTextField(String text)  JTextField(int numOfColumns)  JTextField(String text, int numOfColumns)
  • 36. Swing (JComponent - Παράδειγμα) package simpleFrame; import javax.swing.*; public class SimpleFrame extends JFrame { public static void main(String[] args) { JFrame frame = new JFrame ("My First GUI"); frame.setSize(400,400); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); frame.setLayout(null); JLabel label = new JLabel("JLabel"); JTextField text = new JTextField(); JButton button = new JButton("OK"); label.setBounds(10,10,100,20); text.setBounds(100, 10, 100, 20); button.setBounds(100,50,60,20); frame.add(label); frame.add(text); frame.add(button); } }