Полиморфизм и instanceof

Я запрограммировал класс Worker и MachineWorker. Соответствует нормально. но когда я запускаю его, после трех последовательных операторов программа останавливается. Я не могу найти проблему и не знаю, как и когда использовать instanceof. Я пишу вопрос ниже и со всеми классами...

Вопрос: (i) Объявите массив, который может хранить ссылки до 5 объектов Worker или MachineWorker. а) Разрешить пользователю вводить тип объекта и данные для этого типа объекта (3 значения для Worker и 4 значения для MachineWorker). б) Построить соответствующий объект, хранящий ссылку в общем массиве.

ii) Теперь разрешите пользователям повторно вводить еженедельные данные. Если это объект Worker, пользователь должен ввести ID и количество отработанных часов. Если это объект MachineWorker, пользователь должен ввести идентификатор, количество отработанных часов и штук. После того, как эти значения прочитаны, выполните поиск по массиву, чтобы найти объект с заданным идентификатором, прежде чем вызывать addWeekly(). Количество аргументов (1 или 2), которые будут переданы в addWeekly зависит от типа объектов, на которые ссылаются. Чтобы определить тип ссылаемого объекта (Worker или MachineWorker), вы можете использовать оператор instanceof.

Пожалуйста, смотрите мои коды ниже: -

 //Worker.java
    public class Worker { 
            public final double bonus=100;    
            protected String name, workerID;
            protected double hourlyRate, totalHoursWorked,tax,grossSalary,netSalary;

            public Worker(){

        }
    public Worker(String name, String workerID, double hourlyRate){
        this.name = name;
        this.workerID = workerID;
        this.hourlyRate = hourlyRate;

        }

    public void addWeekly(double hoursWorked){
        this.totalHoursWorked = this.totalHoursWorked + hoursWorked;
        }

    public double gross(){
        grossSalary = (totalHoursWorked*hourlyRate);
                if(totalHoursWorked>=150){
            grossSalary = grossSalary +100;
            }
            return  grossSalary;
            }
    public double netAndTax(){
        netSalary = grossSalary;
        if(grossSalary>500){
            tax = (grossSalary - 500) *0.3;
            netSalary = (grossSalary - tax);

        }
        return netSalary;
     }
    public String getName(){
        return this.name;
    }

    public String getWorkerID(){
        return this.workerID;
    }

    public double getHourlyRate(){
        return this.hourlyRate;
    }

    public double getTotalHours(){
        return totalHoursWorked;
    }

    public double getGrossSalary(){
        return grossSalary;
        }

    public void addToGross(double amt){
        grossSalary = grossSalary + amt;
    }
    public void displaySalary(){
        System.out.print("Name: " +getName() + "\nID :" + getWorkerID() 
                + "\nHourly Rate: " + getHourlyRate()+ "\nTotalHours Worked" + getTotalHours() + 
                "\nGross pay" + getGrossSalary() + "\nTax: " + netAndTax() + 
                "\nNet Pay: " + netAndTax());
    }

    }




//MachineWorker.java
    public class MachineWorker extends Worker{

        private double targetAmount;
        private double totalPieces, productivityBonus;

        public MachineWorker(String workerName, String workerID, double hourlyRate, double targetAmount)
        {
            super(workerName, workerID, hourlyRate);
            //this.productivityBonus = productivityBonus;
            this.targetAmount = targetAmount;

        }

        public void addWeekly(double hoursWorked, double weeklyAmount)
        {
            totalHoursWorked = hoursWorked + totalHoursWorked;
            totalPieces = weeklyAmount + totalPieces;
        }


        public double productivityBonus()
        {
            productivityBonus = 100 + (totalPieces - targetAmount);
            return productivityBonus;
        }

        public double gross()
        {
            grossSalary = (totalHoursWorked * hourlyRate) + productivityBonus;
            if(totalHoursWorked >= 150)
            {
                grossSalary = grossSalary + bonus;
            }
            return  grossSalary;
        }

        public void addToGross(double amt)
        {
            amt = productivityBonus;
            grossSalary = grossSalary + amt;
        }


        public void displaySalary()
        {

        System.out.println("Name    " + super.name + "\nID  " + 
        super.workerID + "\nHourly rate " + super.hourlyRate + "\nTotal Hours Worked    " + 
        super.totalHoursWorked + "\nGross Pay   $" + super.grossSalary + "\nTax $" + super.tax + "\nNetpay  $" + super.netSalary);
            System.out.println("Productivity Bonus  " + productivityBonus);
        }   
    }





  //Polymorphism PolyWorker.java

import java.util.*;
        public class PolyWorkers
    {
        public static void main(String args[])
        {
            Scanner input = new Scanner(System.in);

            Worker[] a = new Worker[5];
            MachineWorker[] b = new MachineWorker[5];

            char option = '0';
            String choice;
            boolean nChar = false;

            for (int i = 0; i < 5; i++){

                System.out.print("\tType of object " + (i+1) + " [W/M]: ");
                choice = input.nextLine();

                if (choice.length() == 1)
                {
                    option = choice.charAt(0); //pick the first character

                    if (option == 'w' || option == 'W')
                    {
                        System.out.println("\n\tEnter name, ID and hours:   ");
                        String name = input.nextLine();
                        System.out.print("  ");
                        String id = input.nextLine();
                        System.out.print("  ");
                        double hours = input.nextDouble();

                        a[i] = new Worker(name, id, hours);
                        System.out.println();

                    }
                    if (option == 'm' || option == 'M')
                    {
                        System.out.print("\n\tEnter name, ID, hours and pieces: ");
                        String name = input.nextLine();
                        System.out.print("  ");
                        String id = input.nextLine();
                        System.out.print("  ");
                        double hours = input.nextDouble();
                        System.out.print("  ");
                        double pieces = input.nextDouble();

                        b[i] = new MachineWorker(name, id, hours, pieces);
                        System.out.println();
                    }
                System.out.print("\tType of object " + (i+1) + " [W/M]: ");
                choice = input.nextLine();
                }


                a[i].displaySalary();
                b[i].displaySalary();
                b[i].productivityBonus();

            }

        }
    }

person bleach64    schedule 15.10.2012    source источник
comment
Я не предоставил классы драйверов, если они вам нужны, я сразу же выложу их.   -  person bleach64    schedule 15.10.2012
comment
Трассировка стека вашей ошибки была бы полезна.   -  person The Cat    schedule 15.10.2012
comment
Я новичок в программировании. Я старался изо всех сил для этой программы, но все еще застрял. Мне нужна помощь профессионалов или рекомендации. Было бы очень полезно, если бы моя проблема была решена   -  person bleach64    schedule 15.10.2012


Ответы (3)


Возможно, вы захотите использовать переопределенные методы readfromInput и displaySalary, чтобы различать действия Worker и Machinworker. Другое поведение должно быть реализовано внутри классов, а не в вызывающем классе Polyworker. Если Machineworker displaySalary показывает бонус, это должно быть вызвано в displaySalary of MachineWorker.

см. измененный код ниже

//Worker.java
import java.util.Scanner;

/**
 * a generic worker
 */
public class Worker {
    public final double bonus = 100;
    protected String name, workerID;
    protected double hourlyRate, totalHoursWorked, tax, grossSalary, netSalary;


    public void addWeekly(double hoursWorked) {
        this.totalHoursWorked = this.totalHoursWorked + hoursWorked;
    }

    public double gross() {
        grossSalary = (totalHoursWorked * hourlyRate);
        if (totalHoursWorked >= 150) {
            grossSalary = grossSalary + 100;
        }
        return grossSalary;
    }

    public double netAndTax() {
        netSalary = grossSalary;
        if (grossSalary > 500) {
            tax = (grossSalary - 500) * 0.3;
            netSalary = (grossSalary - tax);

        }
        return netSalary;
    }

    public String getName() {
        return this.name;
    }

    public String getWorkerID() {
        return this.workerID;
    }

    public double getHourlyRate() {
        return this.hourlyRate;
    }

    public double getTotalHours() {
        return totalHoursWorked;
    }

    public double getGrossSalary() {
        return grossSalary;
    }

    public void addToGross(double amt) {
        grossSalary = grossSalary + amt;
    }

    public void displaySalary() {
        System.out.print("Name: " + getName() + "\nID :" + getWorkerID()
                + "\nHourly Rate: " + getHourlyRate() + "\nTotalHours Worked"
                + getTotalHours() + "\nGross pay" + getGrossSalary() + "\nTax: "
                + netAndTax() + "\nNet Pay: " + netAndTax());
    }

    public void readFromInput(Scanner input) {
        name = input.nextLine();
        System.out.print("  ");
        this.workerID= input.nextLine();
        System.out.print("  ");
        this.totalHoursWorked = input.nextDouble();
        System.out.println();
    }

} // Worker

//MachineWorker.java
import java.util.Scanner;
public class MachineWorker extends Worker {

    private double targetAmount;
    private double totalPieces, productivityBonus;

    public void addWeekly(double hoursWorked, double weeklyAmount) {
        totalHoursWorked = hoursWorked + totalHoursWorked;
        totalPieces = weeklyAmount + totalPieces;
    }

    public double productivityBonus() {
        productivityBonus = 100 + (totalPieces - targetAmount);
        return productivityBonus;
    }

    public double gross() {
        grossSalary = (totalHoursWorked * hourlyRate) + productivityBonus;
        if (totalHoursWorked >= 150) {
            grossSalary = grossSalary + bonus;
        }
        return grossSalary;
    }

    public void addToGross(double amt) {
        amt = productivityBonus;
        grossSalary = grossSalary + amt;
    }

    @Override
    public void displaySalary() {
        super.displaySalary();
        System.out.println("Productivity Bonus  " + productivityBonus);
    }

    @Override
    public void readFromInput(Scanner input) {
        super.readFromInput(input);
        this.totalPieces = input.nextDouble();
    }
}

//Polymorphism PolyWorker.java

import java.util.*;

public class PolyWorkers {
    public static void main(String args[]) {
        Scanner input = new Scanner(System.in);
        Worker[] workers = new Worker[5];

        char option = '0';
        String choice;

        for (int i = 0; i < 5; i++) {

            System.out.print("\tType of object " + (i + 1) + " [W/M]: ");
            choice = input.nextLine();

            if (choice.length() == 1) {
                option = choice.toLowerCase().charAt(0); // pick the first character
                switch (option) {
                case 'w': {
                    workers[i] = new Worker();
                    System.out.println("\n\tEnter name, ID and hours:   ");
                }
                    break;
                case 'm': {
                    System.out.print("\n\tEnter name, ID, hours and pieces: ");
                }
                    break;
                } // switch
                workers[i].readFromInput(input);
            }

            workers[i].displaySalary();
        }

    }
}
person Wolfgang Fahl    schedule 15.10.2012

В вашем вопросе говорится, что вы должны хранить ссылки в общем массиве, где вы храните их в двух разных массивах a и b. Поскольку у вас есть разные массивы для разных типов объектов, вам не нужно использовать оператор instanceOf. Подробнее об instanceOf читайте здесь.

Кроме того, вы не проверяете значение null при печати зарплаты или бонуса. Как и в любой точке цикла, будет создан объект только одного типа, один из a[i] или b[i] будет однозначно нулевым, вызывая исключение NullPointerException.

person Pradeep Pati    schedule 15.10.2012

Вам нужен еще один цикл после того, который вы уже написали, который позволит пользователю вводить часы рабочего. Предположительно, это будет цикл while, который будет постоянно запрашивать ввод. Затем вы должны выбрать какой-то вход, который выйдет из цикла. Внутри цикла вы запрашиваете часы и принимаете либо 2, либо 3 аргумента.

На данный момент вы не храните своих рабочих/машинных рабочих. Вам нужно создать массив для их хранения. Вам также необходимо создать либо базовый класс, либо интерфейс, который они оба будут расширять/реализовывать. Это позволит вам создать единый массив для их хранения.

Затем вы перебираете свой массив Workers/MachineWorkers, и когда вы находите соответствующий идентификатор, вы используете свой instanceof, чтобы решить, нужно ли вам передать 1 или 2 аргумента. Если это MachineWorker, вы должны привести его как таковой, а затем вызвать соответствующий метод с двумя аргументами.

person BeRecursive    schedule 15.10.2012
comment
В 'ID' почему instanceof, подумал я, сравнивая массив. Мне нужно использовать экземпляр - person bleach64; 15.10.2012
comment
Вы находите соответствующий объект с соответствующим идентификатором, а затем используете instanceof, чтобы узнать, к чему его привести. - person BeRecursive; 16.10.2012