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

Απορια στην Java(List)


Επισκέπτης

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

Επισκέπτης
Δημοσ.

Παιδια θελω τη βοηθεια σας.Εχω ενα προγραμμα με την εξης ιεραρχια.Μια κλαση 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 ή όχι και πως αλλιώς μπορώ να κάνω την ίδια δουλειά.

Δημοσ.

Θα βοηθούσε αν μας έλεγες και ποιο είναι το το σφάλμα που σου βγάζει.

Είναι compile time ή run time error;

 

Όσο το βλέπω πάντως νομίζω ότι απλά το list.get(i).getEmpID() επιστρέφει null διότι σε κανέναν από τους δύο Employee που αρχικοποιείς δεν θέτεις κάπου EmpID εκτός και αν γίνεται generate κάπου εσωτερικά.

 

HTH

:-)

Δημοσ.

>
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 κατα τη διαρκεια εκτελεσης.

Δημοσ.

Κάνε τη λίστα τύπου Employee.

 

Στη συνέχεια, έχεις να καλέσεις μέσα στη for() κάποιες μεθόδους. Αυτές οι μέθοδοι είναι ίδιες στις δύο υποκλάσεις, εκτός από την payment(), η οποία όμως μπορεί να οριστεί ως abstract στην Employee (παρόλο που ο ορισμός της θα είναι διαφορετικός στις δύο υποκλάσεις) και άρα να είναι προσβάσιμη από μια λίστα τύπου Employee.

Επισκέπτης
Δημοσ.

Παιδια σας ευχαριστω πολυ για τις απαντησεις σας.Το προβλημα λυθηκε με τη χρηση γενικευσης.Εχω και αλλη μια ερωτηση.Θελω στο πρωτο αντικειμενο που δημιουργω(εδω semp) να δινω την τιμη 1 στο EmpID,στο δευτερο την τιμη 2 και ουτω καθεξης.πως θα το κανω?

Δημοσ.

Θα φτιάξεις μια ανεξάρτητη κλάση.

 

>public class Global
{
   public static long EmpID = 1;
}

 

Μετά, στον constructor της Employee θα γράψεις κάτι σαν αυτό.

 

>EmpID = Global.EmpID;
Global.EmpID = this.EmpID + 1; 

Επισκέπτης
Δημοσ.

Σωστο αυτο που λες αλλα η EmpID πρεπει να ειναι δηλωμενη ως private μεσα στην κλαση Employee.Καμια ιδεα? Σ'ευχαριστω που βοηθας.

Δημοσ.

Θα έχεις σίγουρα μία 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.

 

:-)

Δημοσ.

Μπορούν να δέχονται οι 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 οποτεδήποτε και μάλλον δεν θα το ήθελες (μαλλον γι'αυτό δεν υπάρχει έτσι κι αλλιώς).

Επισκέπτης
Δημοσ.

Σας ευχαριστω παρα πολυ παιδια.Δουλεψε τελικα με την προταση του teo64x.

Δημοσ.

Δεν μπορεί απλά να έχει ενα static field μέσα στο parent?

 

Επίσης: Global.EmpID++; <- αυτό δεν θα δούλευε;

Δημοσ.

Αντι να κανεις 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");
         }

Δημοσ.
Αντι να κανεις 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(). :-)

Δημοσ.

 

Επίσης: Global.EmpID++; <- αυτό δεν θα δούλευε;

 

Γιατι οχι; Δεν ειναι final, απλα μια static ειναι.

 

Teo τωρα το ειδα... Εχεις δικαιο.

Μου ηρθε μια ιδεα...

Στην εισαγωγη των δεδομενων, να ψαξει στη λιστα για το μεγαλυτερο id , με αποτελεσμα το επομενο id να ειναι maxid+1. Τι λες? (Για να αποφυγει τα static)

Δημοσ.

Βλέπω ότι τα αντικείμενα προστίθενται στη λίστα μετά τη δημιουργία τους (και άρα θα παίρνουν το EmpID από μία μέθοδο έξω από το constructor τους). Αν αυτό καλύπτει αυτό που ψάχνει ο topic starter, είναι μια χαρά. Η static στη Global ήταν απλά ο πρώτος τρόπος που μου ήρθε στο μυαλό. :P

Αρχειοθετημένο

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

  • Δημιουργία νέου...