Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Τι εννοείς δε γίνεται ?

Αφού δουλεύει...

 

Πάντως αν δε γίνεται, δεν μπορώ να καταλάβω το νόημα μιας ArrayList<Υπερκλάση> Και σε αυτην να αποθηκεύουμε αντικείμενα υποκλάσεων.

Δε λέω εξυπηρετεί την εννοια του πολυμορφισμού αλλά τι νόημα έχει αν μετά δεν μπορείς να χρησημοποιήσεις τις μεθόδους των αντικείμένων που βρίσκονται στην ArrayList..?

 

Αυτό που έγραψα όντως γίνεται -- το σχόλιο ότι οι παρενθέσεις είναι τζάμπα ήταν για αστείο: στο σημείο αυτό είναι εξαιρετικά σημαντικές.

 

Ο λόγος που συμβαίνουν αυτά είναι πολύ απλός: η σύνταξη

>(Vehicle)v

κάνει μετατροπή τύπου και παράγει μια προσωρινή αναφορά τύπου Vehicle. Όμως όταν γράφεις

>(Vehicle)v.print()

η τελεία (κλήση μεθόδου) έχει μεγαλύτερη προτεραιότητα από την παρένθεση που είναι στα αριστερά, άρα η σύνταξη είναι σαν να σημαίνει (Vehicle)void [αφού μάλλον void επιστρέφει η print()] και κάτι δεν πάει καλά, προφανώς.

 

Όμως αν βάλεις την παρένθεση

>((Vehicle)v).print()

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

 

Το παρακάτω είναι ακριβώς το ίδιο αλλά σε δύο βήματα.

Και μια παρατήρηση: δεν δημιουργείται προσωρινό αντικείμενο αλλά μόνο μία προσωρινή αναφορά. Αντικείμενο δημιουργείται μόνο με το new.

Από οτι φαινεται στην Java μετα απο δοκιμές που έκανα πρέπει να φτιάξεις ενα προσωρινό αντικείμενο πρώτα. Ισως γινεται και χωρίς να το κάνεις, αλλα δεν ειμαι σίγουρος πως.

 

>
public static void main(String[] args)
{
  	Object v = new Vehicle(6,2200.0,4.9,95);
  	
  	Vehicle vt = (Vehicle)v;
  	vt.print();
}

edit: Επειδή φευγω τώρα και δεν εχω πολύ χρόνο κοιτα για τον τελεστή instanceof

 

 

Όσο για την άλλη ερώτησή σου:

Δε λέω εξυπηρετεί την εννοια του πολυμορφισμού αλλά τι νόημα έχει αν μετά δεν μπορείς να χρησημοποιήσεις τις μεθόδους των αντικείμένων που βρίσκονται στην ArrayList..?

 

Η ουσία της κληρονομικότητας είναι ότι έχεις κλάσεις που έχουν τις ίδιες δυνατότητες (μεθόδους) οι οποίες όμως λειτουργούν λίγο διαφορετικά (μία μέθοδος στην υποκλάση μπορεί να υπερβαίνει την αντίστοιχη μέθοδο της υπερκλάσης). Ο λόγος που ομαδοποιείς τα αντικείμενά σου, π.χ. σε ένα ArrayList, είναι για να τα βάλεις να κάνουν τις ίδιες λειτουργίες, με τον τρόπο όμως που ξέρει το καθένα, δηλαδή πολυμορφικά. Πλέον δεν σε ενδιαφέρει ποιος ακριβώς είναι ο τύπος του κάθε αντικειμένου, μόνο το ότι όλα υπακούουν στην κοινή προδιαγραφή της υπερκλάση. Αν θέλεις να κάνεις κάτι που αναφέρεται στη συγκεκριμένη κλάση του αντικειμένου, πρέπει να χρησιμοποιήσεις τον πραγματικό τύπο του με τους τρόπους που αναφέρθηκαν παραπάνω.

Δημοσ.

να κάνω μια ερώτηση μπορεί και λανθασμένη.... γιατί στη main ορίζεις το αντικείμενο σαν object... αφού εσύ θες να φτίαξεις αντικείμενο της Vehicle...

 

>Vehicle1 v = new Vehicle1(6,2200.0,4.9,95);

 

και θα τρέξει μια χαρά πιστεύω... :/

Δημοσ.

να κάνω μια ερώτηση μπορεί και λανθασμένη.... γιατί στη main ορίζεις το αντικείμενο σαν object... αφού εσύ θες να φτίαξεις αντικείμενο της Vehicle...

 

>Vehicle1 v = new Vehicle1(6,2200.0,4.9,95);

 

και θα τρέξει μια χαρά πιστεύω... :/

 

Γιατί είχα στο μυαλό μου ας πούμε να φτιάξω μια κλάση "Database" μέσω της οποίας θα υλοποιώ μία ArrayList<Object> με αποτέλεσμα να βάζω ότι μα ότι θέλω εκεί μέσα...

Δημοσ.

ας πούμε ότι η ArrayList σου έχει την μεταβλητή list,

δοκίμασες να κάνεις Object obj = (Object) v;(όπου v το Vecicle αντικείμενο)

και μετά πας στην λίστα και κάνεις list.add(obj)

 

το δοκίμασες έτσι να δεις αν δουλεύει;

Δημοσ.

ας πούμε ότι η ArrayList σου έχει την μεταβλητή list,

δοκίμασες να κάνεις Object obj = (Object) v;(όπου v το Vecicle αντικείμενο)

και μετά πας στην λίστα και κάνεις list.add(obj)

 

το δοκίμασες έτσι να δεις αν δουλεύει;

 

Αν έχεις ένα ArrayList<Object> δεν θα χρειαζόταν η προσωρινή μετατροπή σε Object αλλά για οποιοδήποτε αντικείμενο v θα μπορούσες άμεσα να κάνεις list.add(v).

Αυτό γιατί η Object είναι υπερκλάση οποιασδήποτε άλλης και επομένως ένα οποιοδήποτε αντικείμενο μπορεί να αντιστοιχιστεί σε μια αναφορά Object.

Δημοσ.

Αν έχεις ένα ArrayList<Object> δεν θα χρειαζόταν η προσωρινή μετατροπή σε Object αλλά για οποιοδήποτε αντικείμενο v θα μπορούσες άμεσα να κάνεις list.add(v).

Αυτό γιατί η Object είναι υπερκλάση οποιασδήποτε άλλης και επομένως ένα οποιοδήποτε αντικείμενο μπορεί να αντιστοιχιστεί σε μια αναφορά Object.

 

Μα ναι!

Δεν μου λες κάτι καινούριο τώρα...

Από αυτό προέκυψε η αρχική μου ερώτηση...

Ήξερα και είχα σκεφτεί εξ αρχής αυτό που λες..

Απλά έλεγα ότι καλό αυτό.. αλλά αν συγκεντρώνεις τα αντικείμενα σε μια ArrayList<Object> και δεν μπορείς να χρησιμοποιείς τις μεθόδους του καθενός ξεχωριστά δεν έχει νόημα...

Ευτυχώς όμως με ένα απλό casting όλα λύνονται :)

Δημοσ.

Βασικά δεν λύνονται διότι η Object δεν έχει τις μεθόδους που έχουν οι δικές σου Class και αν θες να τρέξεις μία μέθοδο από το αντικείμενο, δεν θα ξέρεις αντικείμενο ποιας Class είναι και στο Compile θα έχεις πρόβλημα. Επίσης δεν χρειάζεται να έχεις ArrayList<Object> διότι η ArrayList έχει εκ του φυσικού της αντικείμενα Object εκτός αν ορίσεις εσύ άλλο τύπο. Γενικά πάντως δεν χρησιμοποιούμε την Object έτσι διότι καταργούμε την έννοια του αντικειμενοστραφή προγραμματισμού. Αν είναι να το κάνεις έτσι γιατί δεν κάνεις απλά μία void λίστα σε C; την ίδια δουλειά θα κάνει.

Δημοσ.

Βγάλε την δήλωση package object;

 

public class Vehicle extends Object

{

int rodes;

double weight;

double lenght;

int topSpeed;

public Vehicle(int rodes, double weight, double lenght, int topSpeed)

{

this.rodes = rodes;

this.weight = weight;

this.lenght = lenght;

this.topSpeed = topSpeed;

}

public void print()

{

System.out.println("rodes: "+rodes+"\nvaros: "+weight+"\nmikos: "+lenght+"\nmegisti taxitita: "+topSpeed);

}

 

}

 

 

public class Main

{

public static void main(String[] args)

{

Vehicle v = new Vehicle(6,2200.0,4.9,95);

v.print();

}

}

Δημοσ.

Βασικά δεν λύνονται διότι η Object δεν έχει τις μεθόδους που έχουν οι δικές σου Class και αν θες να τρέξεις μία μέθοδο από το αντικείμενο, δεν θα ξέρεις αντικείμενο ποιας Class είναι και στο Compile θα έχεις πρόβλημα. Επίσης δεν χρειάζεται να έχεις ArrayList<Object> διότι η ArrayList έχει εκ του φυσικού της αντικείμενα Object εκτός αν ορίσεις εσύ άλλο τύπο. Γενικά πάντως δεν χρησιμοποιούμε την Object έτσι διότι καταργούμε την έννοια του αντικειμενοστραφή προγραμματισμού. Αν είναι να το κάνεις έτσι γιατί δεν κάνεις απλά μία void λίστα σε C; την ίδια δουλειά θα κάνει.

 

με τον instanceof δεν μπορώ να ξέρω τι αντικείμενα είναι ?

Δημοσ.

Μπορείς κανονικά με την χρήση if,while,do while

να το ελέγξεις

 

public class Fruit extends Object{}// Κατασκευή Fruit

public class Orange extends Fruit{} // Κατασκευή Orange

 

 

 

Orange orange = new Orange();

 

 

if(orange instanceof Fruit)

{

 

}

 

while(orange instanceof Fruit)

{

}

 

do

{

}

while(orange instanceof Fruit);

Δημοσ.

Μόνο που το instanceof θέλει λίγη προσοχή. Με τις παραπάνω κλάσεις έχουμε π.χ.:

 

>
Fruit f = new Fruit();
Orange o = new Orange();

f instanceof Fruit == true
o instanceof Fruit == true   // Προσοχή!

f instanceof Orange == false
o instanceof Orange == true

Όπως το λένε και αρκετά βιβλία, όταν ένα αντικείμενο είναι μίας κλάσης (Orange) που κληρονομεί άλλες (Fruit), τότε έχει και τις δύο κλάσεις, και το instanceof στο δίνει αυτό. Επομένως με το instanceof δεν μπορείς να είσαι σίγουρος για την ακριβή κλάση του αντικειμένου, εκτός και αν αυτή για την οποία ελέγχεις δεν έχει υποκλάσεις.

 

Υπάρχει επίσης και η μέθοδος getClass() (της Object) η οποία ελέγχει την ακριβή κλάση του αντικειμένου αλλά είναι κάπως πιο δύσκολη στη χρήση της γιατί χρειάζεται να έχεις ένα άλλο αντικείμενο για να συγκρίνεις, π.χ.

 

>
Fruit tmpf = new Fruit();
Orange tmpo = new Orange();

(f.getClass() == tmpf.getClass()) == true
(o.getClass() == tmpf.getClass()) == false

(f.getClass() == tmpo.getClass()) == false
(o.getClass() == tmpo.getClass()) == true

Δημοσ.

Μη ξεχνάς να χρησιμοιποιήσεις και το try catch B)

σε περίπτωση null pointer exception

 

πχ.

try

{

if(f.getClass().equals(tmpf.getClass()))

{

///

}

}catch(Exception Null_Happens)

{

Null_Happens.printStackTrace();

}

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...