Casting στην Java

Συζητήσεις για γλώσσες προγραμματισμού και θέματα σχετικά με προγραμματισμό.
Post Reply
User avatar
sandra
Wow! Terabyte level
Wow! Terabyte level
Posts: 4917
Joined: Mon Oct 02, 2006 11:37 am
Academic status: Alumnus/a
Gender:
Location: στη φωλιά μου κοιτώντας ένα χωράφι με στάρι...

Casting στην Java

Post by sandra » Tue Jul 08, 2008 10:13 am

Καλημέρα. Έχω κάμποσες απορίες με τα αντικείμενα αν μπορεί κάποιος να με βοηθήσει να τα ξεκαθαρίσω.

Έστω ότι έχω δυο τάξεις την Ρ1 και την υποκλάσση της Ρ2. Η Ρ1 έχει μόνο μια μεταβλητή k ενώ η στην Ρ2 έχω ορίσει μόνο την l.
Εάν κάνω:

Code: Select all

P1 one = new P2(); 
το one τι τύπου είναι? Η getClass μου το δίνει μόνο Ρ2 ενώ η instanceof και Ρ1 και Ρ2. Καταλαβαίνω ότι αν είναι Ρ2 είναι λογικό να συμβαίνει αυτό αλλά δεν πιάνω γιατί δεν μπορώ να δω με το one την μεταβλητή l αλλά βλέπω μόνο την k :???: Για να δω και την l πρέπει να κάνω

Code: Select all

((P2)one).l
Εάν τώρα κάνω

Code: Select all

Ρ2 two = (P1)new P2();
στο compile όλα καλά αλλά κατά την εκτέλεση μου σκάει
Exception in thread "main" java.lang.ClassCastException: P1 cannot be cast to P2
Η λογική λέει ότι ένα αντικείμενο Ρ1 δεν είναι απαραίτητα Ρ2 γιαυτό και το πρόβλημα. Αλλά συνεχίζω να μην καταλαβαίνω σε μια τέτοια δήλωση τι τύπου θα είναι το αντικείμενο.

Αν μπορεί να μου εξηγήσει κάποιος τι συμβαίνει στα παρασκήνια :oops: :)
Από εδώ κι εμπρός θα είσαι για πάντα υπεύθυνος για εκείνο που έχεις ημερώσει.
Είσαι υπεύθυνος για το τριαντάφυλλο σου...
User avatar
Fairy
Gbyte level
Gbyte level
Posts: 1733
Joined: Tue Jan 24, 2006 4:48 pm
Academic status: Alumnus/a
Gender:
Location: Mairyland Park

Re: Casting στην Java

Post by Fairy » Tue Jul 08, 2008 10:51 am

Θα κάνω μια προσπάθεια, κι αν έχω επηρρεαστεί βλακωδώς από την C++ ας με διωρθώσει κάποιος (όχι για μένα, αλλά να σώσει και την κοπέλα!)

Όταν γράφεις κώδικα της μορφής

Code: Select all

P1 one = new P2(); 
δημιουργείς μια αναφορά τύπου P1 η οποία δείχνει σε ένα αντικείμενο P2.

Αυτό επιτρέπεται γιατί η τάξη P1 είναι υπερκλάση (και γενικότερη αν θες) της ειδικότερης P2.
Η P2 ως υποτάξη διαθέτει χαρακτηριστικά τόσο δικά της (l) όσο και της P1 (k).
Με μια αναφορά τύπου P1 που φτιάχνεις παραπάνω, λογικά μπορείς να δεις μόνο εκείνα τα χαρακτηριστικά που κληρονομούνται από την υπερτάξη και είναι γνωστά στην P1. Για να δεις και το k και το l πρέπει να φτιάξεις μια αναφορά τύπου P2, ως εξής:

Code: Select all

P2 two = new P2(); 
Από την άλλη δε νομίζω να έχει νόημα και πολύ ο κώδικας

Code: Select all

Ρ2 two = (P1)new P2();
από τη στιγμή που έτσι κι αλλιώς το αντικείμενο P2 διαθέτει τα χαρακτηριστικά της υπερτάξης P1.

O γενικός κανόνας πάντως (αν δεν μπερδεύομαι από τη C++) λέει:
Πως μια δήλωση της μορφής

ΧΤάξη <όνομα αντικ> = new ΨΤάξη();

δημιουργεί μια αναφορά (δείκτη στη μνήμη δηλαδή) προς ένα αντικείμενο τύπου ΨΤάξη. Η αναφορά αυτή είναι εργαλείο που δουλεύει σύμφωνα με τους κανόνες της ΧΤάξης.
"Αν αυτό που έκανες χτες σου φαίνεται ακόμα μεγάλο, δεν έχεις κάνει αρκετά σήμερα."
User avatar
tsilochr
Wow! Terabyte level
Wow! Terabyte level
Posts: 3246
Joined: Tue Mar 16, 2004 2:47 pm
Academic status: PhD
Gender:
Location: mm.aueb.gr
Contact:

Re: Casting στην Java

Post by tsilochr » Tue Jul 08, 2008 1:12 pm

η getClass() είναι μια μέθοδος που σου δίνει την κλάσση του αντικεμένου σου σε runtime, το instanceof είναι ένας τελεστής (όπως το < ή το >=) και αποφασίζει true αν το όρισμα στα αριστερά του τελεστή ανήκει στο δέντρο κληρονομικότητας της κλάσης στα δεξιά του τελεστή

Όταν κάνεις

Code: Select all

P1 one = new P2()
στη μνήμη φτιάχνεται ένα Ρ2 (με k και l) αλλά μέσω της αναφοράς one μπορείς να το χειριστείς μόνο ως Ρ1, δηλαδή να δεις μόνο το k. Αν πεις one.getClass() θα σου επιστρέψει Ρ2 γιατί στη μνήμη είναι όντως P2. Επίσης, τα αντικείμενα τύπου Ρ2 είναι επίσης και Ρ1 άρα η instanceof δίνει true και για Ρ1 και για Ρ2.

Η εντολή

Code: Select all

((P2)one).l
λέει "πάρε το αντικείμενο που χειρίζεται η αναφορά one, κάντο cast σε (δλδ χειρήσου το ως) P2 και δες το πεδίο l." Αν το one στη μνήμη δεν ήταν Ρ2 θα πάρεις ClassCastException.

Η ClassCastException είναι απόγονος της RuntimeException και γενικά τέτοιες εξαιρέσεις ο compiler δεν σε αναγκάζει να τις πιάσεις σε try/catch (αυτό είναι άλλο θέμα)
User avatar
sandra
Wow! Terabyte level
Wow! Terabyte level
Posts: 4917
Joined: Mon Oct 02, 2006 11:37 am
Academic status: Alumnus/a
Gender:
Location: στη φωλιά μου κοιτώντας ένα χωράφι με στάρι...

Re: Serialization Java

Post by sandra » Tue Jul 08, 2008 8:15 pm

Ευχαριστώ και τους δυο σας.
Άλλη απορία άσχετη από casting σχετική με serialization. Διαβάζω ότι όταν περνάς με αυτόν τον τρόπο αντικείμενα σε ένα αρχείο δεν περνιούνται οι transient μεταβλητές και τα στατικά μέλη. Οι πρώτες ΟΚ αυτό θέλουμε να κάνουμε αλλά για το δεύτερο γιατί συμβαίνει αυτό? Δεν θα έπρεπε να περνιούνται? Έστω ένα μόνο αντίγραφο που θα κοίταζε κάθε αντικείμενο τέτοιου τύπου? :smt017
Επίσης αν ένα αρχείο υπάρχει ήδη του κάνει append τα νέα αντικείμενα ή τα γράφει πάνω στα παλιά? Με τα κινέζικά που βγάζει δύσκολο να καταλάβω.
Από εδώ κι εμπρός θα είσαι για πάντα υπεύθυνος για εκείνο που έχεις ημερώσει.
Είσαι υπεύθυνος για το τριαντάφυλλο σου...
User avatar
rose
Gbyte level
Gbyte level
Posts: 1921
Joined: Sun May 20, 2007 8:59 pm
Academic status: 4th year
Gender:

Re: Casting στην Java

Post by rose » Wed Jul 09, 2008 1:07 pm

Ενα ενδιαφέρον άρθρο "γιατι χρησιμοποιούμε το transient" θα το βρείς εδώ http://www.precisejava.com/javaperf/j2s ... zation.htm
οπως είπες το θέλουμε για optimization και performance.

Sometimes, you want to have variables that are common to all objects. This is accomplished with the static modifier. Fields that have the static modifier in their declaration are called static fields or class variables. They are associated with the class, rather than with any object. Every instance of the class shares a class variable, which is in one fixed location in memory. Any object can change the value of a class variable, but class variables can also be manipulated without creating an instance of the class.
http://java.sun.com/docs/books/tutorial ... svars.html

Βασικά αυτό ειναι το θέμα αφού το serialization κάνει apply μονο στο object.
που θα πάει θα το δουμε...
User avatar
sandra
Wow! Terabyte level
Wow! Terabyte level
Posts: 4917
Joined: Mon Oct 02, 2006 11:37 am
Academic status: Alumnus/a
Gender:
Location: στη φωλιά μου κοιτώντας ένα χωράφι με στάρι...

Re: Casting στην Java

Post by sandra » Wed Jul 09, 2008 1:10 pm

Απλά θεώρησα ότι δεν είναι άχρηστες οι static μεταβλητές για το αντικείμενο. Πάντως κάτι που μου έκανε εντύπωση είναι ότι οι transient παρόλο που δεν περνιούνται στο αρχείο όταν κάνεις de-serialization αυτές περνιούνται στο αντικείμενο αλλά με μηδενικά values :)
Από εδώ κι εμπρός θα είσαι για πάντα υπεύθυνος για εκείνο που έχεις ημερώσει.
Είσαι υπεύθυνος για το τριαντάφυλλο σου...
User avatar
rose
Gbyte level
Gbyte level
Posts: 1921
Joined: Sun May 20, 2007 8:59 pm
Academic status: 4th year
Gender:

Re: Casting στην Java

Post by rose » Wed Jul 09, 2008 2:03 pm

Απλά θεώρησα ότι δεν είναι άχρηστες οι static μεταβλητές για το αντικείμενο
΄

Θα έπρεπε....γενικά τα αντικείμενα θα πρέπει να είναι static independent :-D ειμαι ερωτευμένος με αυτη την λέξη! :smt024
που θα πάει θα το δουμε...
Post Reply

Return to “Προγραμματισμός”