2

I'm working on my intro to programming assignment. Previously I created a program that models an employee using classes for Address Name and Date. This week the assignment is adding subclasses for Hourly and Salaried employees. To start with I tried making my employee class abstract, but when I do that, I get an error in my ArrayList "Cannot instantiate the type Employee (I put in a comment that shows where this error is)" I have posted my code below-- If anyone could give me any suggestions I would really appreciate it I've been struggling with what to do for hours.

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public abstract class Employee
{
    private int id;
    private Name name;
    private Address address;
    private Date date;

    Employee (int id, Name name, Address address, Date date) 
    {
        setId(id);
        setName(name);
        setAddress(address);
        setDate(date);
    }

    //Setter
    public void setId(int id) 
    { 
        this.id = id; 
    }
    public void setName(Name name) 
    { 
        this.name = name; 
    }
    public void setAddress(Address address) 
    { 
        this.address = address; 
    }
    public void setDate(Date date) 
    { 
        this.date = date; 
    }

    //Getter
    public int getId() 
    { 
        return id; 
    }
    public Name getName() 
    { 
        return name; 
    }
    public Address getAddress() 
    { 
        return address; 
    }
    public Date getDate() 
    { 
        return date; 
    }
    public String toString()
    {
        return "ID: " +getId()+ "Name: " +getName()+ "Address: " +getAddress()+ "Hire Date: "+ getDate();
    }


    public static void main(String[] args)
    {
        Scanner input = new Scanner(System.in);

        // Ask user for number of employees; create array of appropriate size
        System.out.println("Enter the number of employees: ");
        int numEmployees = input.nextInt();


        List<Employee> employees = new ArrayList<>();

        // Read information on individual employees. 
        for (int i = 0; i < numEmployees; i++) 
        {
            System.out.println("Enter the employee ID number: " );
            int id = input.nextInt();

            input.nextLine(); //without this the scanner skips

            System.out.println("Enter the first name of the employee: " );
            String firstName = input.nextLine();

            System.out.println("Enter the last name of the employee: " );
            String lastName = input.nextLine();

            System.out.println("Enter the street address of the employee: " );
            String street = input.nextLine();

            System.out.println("Enter the city where the employee resides: " );
            String city = input.nextLine();

            System.out.println("Enter the state where the employee resides (two letter abbreviation): " );
            String state = input.nextLine();

            System.out.println("Enter the zip code of the employee: " );
            String zip = input.nextLine();

            System.out.println("Enter the month the employee was hired (1-12): " );
            int month = input.nextInt();

            System.out.println("Enter the day the employee was hired (1-31): " );
            int day = input.nextInt();

            System.out.println("Enter the year the employee was hired (1900-2020): " );
            int year = input.nextInt();

            input.nextLine(); //without this the scanner skips to last name

            Name name = new Name(firstName, lastName);
            Address address = new Address(street, city, state, zip);
            Date date = new Date(month, day, year);   

            //this is where I get the error
            Employee employee = new Employee(id, name, address, date);

            employees.add(employee);
        }

        /**
         * Print out information on all the employees 
         * Use Foreach loop to iterate through ArrayList
         **/
        for(Employee employee : employees) 
        {
            System.out.print("ID:" + employee.getId() + " ");
            System.out.print("Name:" + employee.getName().getFirstName() + " ");
            System.out.println(employee.getName().getLastName());
            System.out.print("Address:" + employee.getAddress().getStreet() + " ");
            System.out.print(employee.getAddress().getCity() + " ");
            System.out.print(employee.getAddress().getState() + " ");
            System.out.println(employee.getAddress().getZip());
            System.out.print("Hire Date: " + employee.getDate().getMonth() + "/");
            System.out.print(employee.getDate().getDay() + "/");
            System.out.println(employee.getDate().getYear());
            System.out.println();
        }
        input.close();
    }
}
Pshemo
  • 122,468
  • 25
  • 185
  • 269
H.P.
  • 29
  • 3

3 Answers3

1

You cannot instantiate abstract classes in Java. You can, however, instantiate a quick non-abstract subclass from them. In this subclass you'd of course need to implement all methods that are abstract as well

abstract class Foo {
 ...
}

public static void main(String args[]) {
  Foo foo = new Foo(); //Can't do
  Foo foo = new Foo() {}; // this will work, as long as Foo has a null constructor; if Foo has abstract methods, make sure to define them concretely within the { ... } block
}
ControlAltDel
  • 33,923
  • 10
  • 53
  • 80
1

Usually abstract classes are used to provide the basic data/methods to subclasses.
You cannot instantiate an object of abstract class.*
It's just a level of program abstraction and a good practice to create a hierarchical class structure.

*But you may use a reference to abstract class for creating an object of a concrete type.

AbstractClass obj = new ConcreteClass(); // if ConcreteClass extends AbstractClass 
Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
  • That makes a lot of sense. I think in that case I should separate out an abstract employee class, and put the main method/asking for user input in a different class. – H.P. Mar 14 '16 at 19:20
  • @H.P., yes, and throw away `abstract` word from `Employee` if you don't have specific classes as `Manager` or `Programmer` for example – Andrew Tobilko Mar 14 '16 at 19:25
0

Making a class abstract usually means that it will be used as a parent class for subclasses that need to implement the same methods. Abstract classes cannot be instantiated. Once you have created your required subclasses, HourlyEmployee and SalariedEmployee, you'll be able to define a new object like this:

Employee employee = new HourlyEmployee();

or

Employee employee = new SalariedEmployee();

Here's a great explanation regarding abstract classes: https://stackoverflow.com/a/1320887/6062407

Community
  • 1
  • 1
R.P.
  • 16
  • 1
  • 4
  • Thank you, that article was very helpful. I wrote up my subclasses HourlyEmployee and SalariedEmployee but I'm not sure how to incorporate them into my ArrayList for user input. Do you have any suggestions? – H.P. Mar 14 '16 at 20:56
  • You just have to create a constructor (for each subclass) with the same parameters as the constructor of your parent class, then invoke `super(id, name, address, date);`. After that you can replace your code in the `for loop` to `Employee employee = new HourlyEmployee(id, name, address, date);` or `Employee employee = new SalariedEmployee(id, name, address, date);`, depending on your needs. You probably have to do some checking (maybe an input and `if statement`?) before instantiation to tell which sub class object you need to create. – R.P. Mar 15 '16 at 16:41