Επισκέπτης Δημοσ. 6 Μαΐου 2009 Δημοσ. 6 Μαΐου 2009 Παιδια θελω τη βοηθεια σας.Εχω ενα προγραμμα με την εξης ιεραρχια.Μια κλαση Employee που εχει δυο υποκλασεις SalariedEmployee και HourlyEmployee.H Employee εχει τις μεθοδους setName,getName,setAfm,getAfm,getEmpID και (abstract)payment.Οι δυο υποκλασεις εχουν απλα τη μεθοδο payment εξειδικευμενη.Παρακατω ειναι ο κωδικας της main μου: >import java.util.*; public class Main { public static void main(String[] args) { ArrayList list = new ArrayList(); SalariedEmployee semp = new SalariedEmployee(); HourlyEmployee hemp = new HourlyEmployee(); list.add(semp); list.add(hemp); semp.setName("Gewrgiou"); semp.setAfm("777777"); semp.setSalary(300000); hemp.setName("Karamitros"); hemp.setAfm("888888"); hemp.setHoursWorked(10); hemp.setHourlyPayment(30000); for(int i=0;i<list.size();i++){ System.out.println("Employee ID: " + [b]list.get(i).getEmpID()[/b]); System.out.println("Employee Name: " + list.get(i).getName()); System.out.println("Employee AFM: " + list.get(i).getAfm()); System.out.println("Employee Payment: " + list.get(i).payment() + "\n"); } } } Το προβλημα μου ειναι το bold.Εκει μου βγαζει σφαλμα.Η απορια μου ειναι αν ειναι η σωστη η εντολη στα bold ή όχι και πως αλλιώς μπορώ να κάνω την ίδια δουλειά.
vag_pRiMi Δημοσ. 6 Μαΐου 2009 Δημοσ. 6 Μαΐου 2009 Θα βοηθούσε αν μας έλεγες και ποιο είναι το το σφάλμα που σου βγάζει. Είναι compile time ή run time error; Όσο το βλέπω πάντως νομίζω ότι απλά το list.get(i).getEmpID() επιστρέφει null διότι σε κανέναν από τους δύο Employee που αρχικοποιείς δεν θέτεις κάπου EmpID εκτός και αν γίνεται generate κάπου εσωτερικά. HTH
Bspus Δημοσ. 6 Μαΐου 2009 Δημοσ. 6 Μαΐου 2009 > for(int i=0;i<list.size();i++){ Employee emp = (Employee) list.get(i); System.out.println("Employee ID: " + emp.getEmpID()); Δεν το αναφερεις, αλλα φανταζομαι το σφαλμα θα ισχυει και στις επομενες γραμμες και οχι μονο στο empid. Αυτο συμβαινει επειδη η λιστα ειναι φτιαγμενη να παιρνει objects γενικως. Το οτι εσυ ξερεις τι ειδους object εχεις βαλει μεσα και τι μεθοδους εχει δεν σημαινει τιποτα για τον compiler. Γι αυτο, πρεπει να κανεις type casting, να του πεις δηλαδη οτι το ταδε object που μολις τσιμπησες απο τη λιστα ειναι αυτου το συγκεκριμενου τυπου, επομενως θα υποστηριζει και τις μεθοδους του. Φυσικα αν κανεις cast σε κατι αυτο που παιρνεις απο τη λιστα δεν ειναι του ιδιου τυπου θα σου πεταξει error κατα τη διαρκεια εκτελεσης.
teo64x Δημοσ. 6 Μαΐου 2009 Δημοσ. 6 Μαΐου 2009 Κάνε τη λίστα τύπου Employee. Στη συνέχεια, έχεις να καλέσεις μέσα στη for() κάποιες μεθόδους. Αυτές οι μέθοδοι είναι ίδιες στις δύο υποκλάσεις, εκτός από την payment(), η οποία όμως μπορεί να οριστεί ως abstract στην Employee (παρόλο που ο ορισμός της θα είναι διαφορετικός στις δύο υποκλάσεις) και άρα να είναι προσβάσιμη από μια λίστα τύπου Employee.
Επισκέπτης Δημοσ. 6 Μαΐου 2009 Δημοσ. 6 Μαΐου 2009 Παιδια σας ευχαριστω πολυ για τις απαντησεις σας.Το προβλημα λυθηκε με τη χρηση γενικευσης.Εχω και αλλη μια ερωτηση.Θελω στο πρωτο αντικειμενο που δημιουργω(εδω semp) να δινω την τιμη 1 στο EmpID,στο δευτερο την τιμη 2 και ουτω καθεξης.πως θα το κανω?
teo64x Δημοσ. 6 Μαΐου 2009 Δημοσ. 6 Μαΐου 2009 Θα φτιάξεις μια ανεξάρτητη κλάση. >public class Global { public static long EmpID = 1; } Μετά, στον constructor της Employee θα γράψεις κάτι σαν αυτό. >EmpID = Global.EmpID; Global.EmpID = this.EmpID + 1;
Επισκέπτης Δημοσ. 6 Μαΐου 2009 Δημοσ. 6 Μαΐου 2009 Σωστο αυτο που λες αλλα η EmpID πρεπει να ειναι δηλωμενη ως private μεσα στην κλαση Employee.Καμια ιδεα? Σ'ευχαριστω που βοηθας.
teo64x Δημοσ. 6 Μαΐου 2009 Δημοσ. 6 Μαΐου 2009 Θα έχεις σίγουρα μία EmpID ως private μέσα στην Employee (που θα είναι ιδιότητα του κάθε αντικειμένου Employee). Η EmpID της Global είναι διαφορετικό πράγμα (και μπορεί να έχει διαφορετικό όνομα αν σε μπερδεύει αυτό) - λειτουργεί απλά ως counter προσβάσιμο από παντού. Δες το πάλι με διαφορετικό όνομα στην καθολική μεταβλητή: >public class Global { public static long ECounter = 1; } >EmpID = Global.ECounter; Global.ECounter = this.EmpID + 1; Το EmpID παραμένει private ιδιότητα του Employee.
vag_pRiMi Δημοσ. 6 Μαΐου 2009 Δημοσ. 6 Μαΐου 2009 Μπορούν να δέχονται οι constructors ένα long ή (String argument). > abstract class Employee { long empID = -1; > public class SalariedEmployee extends Employee { SalariedEmployee(long empID) { this.empID = empID; } και > class HourlyEmployee extends Employee { HourlyEmployee(long empID) { this.empID = empID; } Έτσι με το static του teo64x θα έχεις: > public class Main { public static void main(String[] args) { [b]ArrayList<Employee> list = new ArrayList<Employee>(); SalariedEmployee semp = new SalariedEmployee(Global.empID++); HourlyEmployee hemp = new HourlyEmployee(Global.empID++);[/b] list.add(semp); list.add(hemp); semp.setName("Gewrgiou"); semp.setAfm("777777"); semp.setSalary(300000); hemp.setName("Karamitros"); hemp.setAfm("888888"); hemp.setHoursWorked(10); hemp.setHourlyPayment(30000); for(int i=0;i<list.size();i++){ System.out.println("Employee ID: " + list.get(i).getEmpID()); System.out.println("Employee Name: " + list.get(i).getName()); System.out.println("Employee AFM: " + list.get(i).getAfm()); System.out.println("Employee Payment: " + list.get(i).payment() + "\n"); } } } Εναλλακτικά θα μπορούσες να δημιουργήσεις setEmpID(), αλλά αυτό θα επέτρεπε να αλλάζει το empID οποτεδήποτε και μάλλον δεν θα το ήθελες (μαλλον γι'αυτό δεν υπάρχει έτσι κι αλλιώς).
Επισκέπτης Δημοσ. 6 Μαΐου 2009 Δημοσ. 6 Μαΐου 2009 Σας ευχαριστω παρα πολυ παιδια.Δουλεψε τελικα με την προταση του teo64x.
ippo00 Δημοσ. 7 Μαΐου 2009 Δημοσ. 7 Μαΐου 2009 Δεν μπορεί απλά να έχει ενα static field μέσα στο parent? Επίσης: Global.EmpID++; <- αυτό δεν θα δούλευε;
Evgenios1 Δημοσ. 7 Μαΐου 2009 Δημοσ. 7 Μαΐου 2009 Αντι να κανεις base classes Κλπ... Γιατι πολυ απλα δεν οριζεις το i σαν id ; > for(int i=0;i<list.size();i++){ System.out.println("Employee ID: " + (i+1)); System.out.println("Employee Name: " + list.get(i).getName()); System.out.println("Employee AFM: " + list.get(i).getAfm()); System.out.println("Employee Payment: " + list.get(i).payment() + "\n"); }
teo64x Δημοσ. 7 Μαΐου 2009 Δημοσ. 7 Μαΐου 2009 Αντι να κανεις base classes Κλπ... Γιατι πολυ απλα δεν οριζεις το i σαν id ; > for(int i=0;i<list.size();i++){ System.out.println("Employee ID: " + (i+1)); System.out.println("Employee Name: " + list.get(i).getName()); System.out.println("Employee AFM: " + list.get(i).getAfm()); System.out.println("Employee Payment: " + list.get(i).payment() + "\n"); } Το αποτέλεσμα θα ήταν το ίδιο, απλά η άσκηση του topic starter θέλει το EmpID ως private στην Employee και επίσης θέλει να υπάρχει η μέθοδος getEmpID().
Evgenios1 Δημοσ. 7 Μαΐου 2009 Δημοσ. 7 Μαΐου 2009 Επίσης: Global.EmpID++; <- αυτό δεν θα δούλευε; Γιατι οχι; Δεν ειναι final, απλα μια static ειναι. Teo τωρα το ειδα... Εχεις δικαιο. Μου ηρθε μια ιδεα... Στην εισαγωγη των δεδομενων, να ψαξει στη λιστα για το μεγαλυτερο id , με αποτελεσμα το επομενο id να ειναι maxid+1. Τι λες? (Για να αποφυγει τα static)
teo64x Δημοσ. 7 Μαΐου 2009 Δημοσ. 7 Μαΐου 2009 Βλέπω ότι τα αντικείμενα προστίθενται στη λίστα μετά τη δημιουργία τους (και άρα θα παίρνουν το EmpID από μία μέθοδο έξω από το constructor τους). Αν αυτό καλύπτει αυτό που ψάχνει ο topic starter, είναι μια χαρά. Η static στη Global ήταν απλά ο πρώτος τρόπος που μου ήρθε στο μυαλό.
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.