StackPeople, I have a question. What statement could help me implement the right class before inserting it to the ArrayList. I have declared Nurse and Pilot which are Employees objects.
I want each implementation of my class ArrEmp to store different Employees objects
example: arrEmpNurses, arrEmpPilots,... after my class gets an example in the constructor
What statement helps?? Or should I re think the problem.
Thanks for your help.
THE PROBLEM IS TO FILL THE ARRAY WITH THE RIGHT CLASS (IT WILL READ FROM PLAIN TEXT AND IT NEWS TO BE NOTIFIED WhAT CLASS TO IMPLEMENT TO ADD IT)
"This code compiles, just copy paste."
import java.util.*;
public class ArrEmp {
String[][] data={ {"E1"}, {"Maria"}, {"E2"}, {"John"} }; //Data
Employee x;
static Nurse nancy= new Nurse("01","Nancy");//this are just examples
static Pilot peter= new Pilot("02","Peter");//so the arrayEmp knows what type of employee create
ArrayList arr;
public ArrEmp(Employee x){
this.x=x;
arr= new ArrayList();
fillList();//with data array
}
public void fillList(){// I would like to fill the List with Nurses. How could i do it?
//for( String[] param: data )
//arr.add( ) //insert helpfull statement here
//the goal is to have an array of Pilot and another of Nurses
}
public static void main(String[] args) {
ArrEmp arr1= new ArrEmp( nancy );
ArrEmp arr2= new ArrEmp( peter );
}
public static class Employee {
String cod;
public Employee(String cod){
this.cod=cod;
}
}
public static class Nurse extends Employee{
String name;
public Nurse(String ... para){
super(para[0]);
this.name=para[1];
}
}
public static class Pilot extends Employee{
String name;
public Pilot(String ... para){
super(para[0]);
this.name=para[1];
}
}
}
I asked the question this way because data is actually read from Disk and ArrEmp has no idea what Employee he is reading. i need to provide an example so it builds the right employee and then insert it into the array. so new ArrEmp( nancy ) reads the file and builds Nurses and store them but new ArrEmp( nancy ) reads a file and loads Pilots on it.
EDIT SOLUTION: ESCENTIALLY I WILL CREATE A GENERIC ARRAYLIST EXTENDS EMPLOYEE, and extending classes for each Emlployee object...
Why not use generics? See: Java generics - ArrayList initialization
Essentially use
ArrayList<Nurse>
Instead of ArrayEmp(Nancy) to say it will only contain Nurses, then the language will take care of enforcing it.
public static class Employee {
String name;
int ID = 0;
public Employee(String name){
this.name = name;
}
}
Just use ID's to denote the differentiation between all of them? You can create an ENUM and fill in legible names for differentiating between different objects. It's faster then string comparing and using instanceOf.
public static class Pilot extends Employee{
int ID = 1;
public Pilot(String name){
this.name = name;
}
}
EDIT:
public ArrEmp(Employee x){
if (x.ID == 1) // add to the list you want
else if (x.ID == 2) // add to list you want
....
}
Related
I am new to java. I try to get and change objects from a class ( ex: Class Camera or Class Microphone and objects camera1, camera2, camera3 , microphone1, microphone2, microphone3 in their classes each with price, name, score ) i want to get the name of one object and change one's price from another class without making a new one.
This is the first class:
public class Microphone{
String name;
int price;
/** Constructors, setters and getters */
Microphone mic1 = new Microphone("mic1",200);
Microphone mic2 = new Microphone("mic2",300);}
This is the second class:
public class Camera{
String name;
int price;
/** Constructors, setters and getters */
Camera cam1 = new Camera("cam1",500);
Camera cam2 = new Camera("cam2",1000);}
In the main class ( or in a different class like Shop, menu etc ) i want to get the price of one's object, like cam1.getPrice and mic2.setPrice so i can compare to the stats of the player in the game if he can afford it and to change the price of it.
You can create an ArrayList in your Main class with your object type and manage them this way. You can then modify your objects as much as you'd like. If you create an interface class you can do something like this:
First create the interface class, I named mine Device and gave it one method, to set the cost. You can add whatever methods you need to add, like setDate, setModel, setName.... etc
public interface Device
{
void setCost(double costIn);
}
Next create the microphone class and have it implement Device. After, you will need to add the Device methods to the class.
public class Microphone implements Device
{
double cost = 0.0;
public void setCost(double costIn)
{
cost = costIn;
}
}
Here is another class example with Camera, also with one data member.
public class Camera implements Device
{
double cost = 0.0;
public void setCost(double costIn)
{
cost = costIn;
}
}
Now in your main class, you can have all of your Devices into one ArrayList for easy manipulation and control.
public static void main(String[] args) throws FileNotFoundException
{
ArrayList<Device> arr = new ArrayList<Device>();
arr.add(new Microphone());
arr.add(new Camera());
}
Honestly there is a lot of ways to go about what you are asking, this is just one example.
Create a class(It is also known as model class) such as Car.
Then define relevent attributes inside that class.
Put the full args constructor.
Make setters & getters.
public class Car {
private String name;
Car(String name){
this name=name;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
So you can change or get on created object using getters & setters.
example : Car c1= new Car("Audi"); If you want to change name of Car
c1.setName("Toyota");
I have a problem with a task I have to do. I need to create class Company and write few methods (such as hire, fire, etc.) for Employee class objects.
Those are my classes and methods:
public class Company{
ArrayList <Employee> alist= new ArrayList<Employee>();
public void hire(Employee e) {
int i=0;
boolean k=false;
while(i<alist.size()) {
if (e.getLastName().equals(alist.get(i).getLastName())) {
k=true;
i++;
}
}
if (k==false) alist.add(e);
else System.out.print("Employee already exists");
}
}
public class Employee{
protected String lastname; //protected for subclasses
protected double jobposition;
public Employee(String lastname,double jobposition) {
this.lastname=lastname;
this.jobposition=jobposition;
}
public String getLastName() {
return lastname;
}
And subclass which extends Employee:
public class OfficeWorker extends Employee {
float pay, bonus;
public OfficeWorker(String lastname,double jobposition,float pay,float bonus) {
super(lastname,jobposition);
this.pay=pay;
this.bonus=bonus;
}
}
I wanted to use ArrayList to do this, but it crashes in main class and I get message "The method hire(Employee) is undefined for the type ArrayList":
public static void main(String[]args) {
ArrayList <Employee> list = new ArrayList <Employee>();
Employee e1 = new OfficeWorker("Smith",0.5,2000,50);
list.hire(e1);
}
Why can't I do this like that?
Your main method should be like:
public static void main(String[]args) {
Company company = new Company();
Employee e1 = new OfficeWorker("Smith",0.5,2000,50);
company.hire(e1);
}
As you have already written method hire() in class Company which adds the Employee in the ArrayList <Employee> alist.
There is NO way you can create your own method in Java ArrayList class.
ArrayList list = new ArrayList ();
ArrayList don't have hire method.
In a class you can access the method availabe in that method.And that also depends upon access modifier and where you are aceesing the method.
To access a non-static public method you have to create object and call method on that object
SomeClass c=new SomeClass();
c.m();
For static public method you can call directly
SomeClass.m();
hire() method is defined as part of Company Class.
it should be as below.
Company xyz = new Company();
xyz.hire(e1);
What's happening is that you are calling the method hire directly into the ArrayList object, instead of that, create an object called Company, then, once it's created, call the method of hire in the Company, as the Company already has the property of ArrayList in it.
public static void main(String[]args) {
Company company = new Company();
Employee e1 = new OfficeWorker("Smith",0.5,2000,50);
company.hire(e1);
}
Hope it helps!
Is it possible (or sensible) to use an object in it's own constructor?(Sorry for the poorly formulated noob question)
Say I have a class "Students" which contains an arrayList of subclass Student and a method for adding new students to the array.
Can I in my Student constructor use the addStudent method to add the new instance to the array on creation?... like so:
//Students
class Students{
private static ArrayList<Student> STUDENTS = new ArrayList<>();
public static void addStudents(Student student){
STUDENTS.add(student);
}
}
//Student
class Student /*extends Students <- old misstake left for reference*/{
private String name = "";
private int birthYear = 0;
Student(String _name, int _birthYear){
this.name = _name;
this.birthYear = _birthYear;
//insert wild guess
Students.addStudents(this(name,birthYear));
}
}
Or will this simply loop and create a lot of objects until everything crashes?
You can; you just shouldn't.
One reason is that you might not always want to add all Student instances to the same shared list. For example, if you're creating Student instances in a unit test, and adding them into the Students list in the constructor, you then have to worry about clearing the list after the test, to avoid accidentally sharing state between tests.
Another reason is that adding the instance in the constructor is called unsafe publication. You are giving out a reference to an instance which has not been fully initialized. This can lead to some very tricky bugs, especially related to concurrency.
You should always wait until an instance has been fully initialized (i.e. one new Whatever has returned) before you do anything with it.
You would be better decoupling creating the Student from adding to the Students list. Use a factory method to create students:
class Students{
private static ArrayList<Student> STUDENTS = new ArrayList<>();
public static void addStudents(Student student){
STUDENTS.add(student);
}
// Factory method.
public static Student createAndAddStudent(String name, int birthYear) {
Student student = new Student(name, birthYear);
addStudents(student);
return student;
}
}
In terms of your current code, you don't need extends Students. Logically, Student isn't a Students, any more than a Car wouldn't be a Cars (say it out loud; it just doesn't make sense).
All you need to do is to invoke the static method:
class Student {
Student() {
// ...
Students.addStudents(this);
// ...
}
}
You are using the keyword this incorrectly. You don't send any values along with this. this is a reference to the current object.
The benefit of using this way is that you'll never had to individually add all of the students to a list. Along with this it will save you the hassle of accidentally forgetting to add one to your array.
class Student extends Students{
private String name = "";
private int birthYear = 0;
Student(String _name, int _birthYear){
this.name = _name;
this.birthYear = _birthYear;
addStudents(this);
}
public static void main(String[] args){
Student s = new Student("Ryan", 1999);
}
}
I'm trying to cover OOP stuffs but I stuck here. I get error in Company class, employees[0].setBonus(50) part. Isn't there any other way to solve it except defining Bonus methods in Employee class? Or is there anyway to keep all objects in one array? I defined bonus methods but there was another thing, what I have to return in Empoyee class' getBonus method?
public class Company
{
private static Employee[] employees;
public Company()
{
employees= new Employee[]{new Manager("Sapo",10000),new Employee("James",5000),new Employee("Jessie",5001)};
}
public static void main(String[] args)
{
Company company= new Company();
employees[0].setBonus(50);
System.out.println(employees[0].getBonus());
}
}
public class Employee extends Person
{
int salary;
public Employee(String name,int salary) {
super(name);
setSalary(salary);
// TODO Auto-generated constructor stub
}
public void setSalary(int salary)
{
this.salary= salary;
}
public int getSalary()
{
return salary;
}
}
public class Manager extends Employee
{
private int bonus;
public Manager(String name, int salary) {
super(name, maas);
}
public void setBonus(int bns)
{
bonus=bns;
}
public int getBonus()
{
return bonus;
}
public int getSalary()
{
return salary+bonus;
}
}
I'm confused.
If you really want do it this way, you can cast employee[0] as manager, but You must know is not nice solution. E.g:
Company company= new Company();
Manager manager = Manager.class.cast(employees[0]);
manager.setBonus(50);
System.out.println(manager.getBonus());
Or is there anyway to keep all objects in one array?
You could but it would force you to write :
if ( employees[0] instanceof Manager){
((Manager) employees[0]).setBonus(50);
}
which is not a good practice.
Functionally, if a bonus is a property which owns only the Manager instances, an Employee instance should not try to set or get it.
When you do :
employees[0].setBonus(50);
the compiler doesn't know the concrete instance. It sees only Employee.
In this very simple code, we see straight that the first employee is a manager but in a real application the array may be modified multiple times. Trying to remember at which indexes are the managers is error prone. If you need to call a manager specific method on a or several managers you should be sure about knowing which variables are managers. So declaring them as manager seems the more natural way.
To solve your problem, two arrays seems more interesting : one for employees and another for managers :
private static Employee[] employees;
private static Manager[] managers;
Now you can do :
public Company()
{
employees= new Employee[]{new Employee("James",5000),new Employee("Jessie",5001)};
managers= new Employee[]{new Manager("Sapo",10000)};
}
public static void main(String[] args){
Company company= new Company();
managers[0].setBonus(50);
System.out.println(managers[0].getBonus());
}
Your abstraction is wrong. You see, the compiler only has that information that is available at compile time.
You have an array of Employee objects there. It doesn't matter that your code at run time will put a Manager object into that array! The compiler doesn't know that. He only knows that there is an Employee.
And the Employee class has no method setBonus(). Thus you can't call that method!
One possible solution would be for example to make the bonus a parameter to the constructor of Manager; the whole think could look like this:
public class Manager extends Employee {
private final int bonus;
public Manager(String name, int salary, int bonus) {
super(name, salary);
this.bonus = bonus;
}
#Override
int getSalary() {
return super.getSalary() + bonus;
}
Notes:
You should avoid to use fields of your super class; those are private implementation details of that class. Child classes should not care about them. Instead, you could call the method from the super class.
On the other hand, you should strive for making your fields final. That makes a lot of things much easier.
When overriding methods ... use the #Override annotation!
Finally: a constructor is a bad place to create your "test data". In other words: your main method is to place to create that array of employees; and then you just pass that into your Company constructor. You want to clearly separate your "real business logic" from that stuff that mainly exists to test that "business logic".
I have a class
public class Company {
public String b;// boss
public String n;// name
public Company(String boss, String name){
b=boss;
n=name;
}
public void print(){
JOptionPane.showMessageDialog(null, b +n);
}
}
And a class that extends it
public class MB extends Company {
public static String b;// boss
public static String n;// name
private static String p;//product
public MB(String boss,String name,String product){
super(b,n);
p=product;
}
#Override
public void print(){
JOptionPane.showMessageDialog(null,super.b +super.n +p);
}
Class MB when I do print method I get null null and p value. Why is that? Shouldn't b and n be inherited from the class Company. I am new to JAVA so I might have missed something but reading previous questions and JAVA docs I couldn't find the answer. Personally I think the mistake is
public static String b;// boss
public static String n;// name
But cant figure out how to solve it.
In
super(b,n);
you're passing b and n which refer to your static variables which have yet to be initialized and are therefore null. Perhaps you meant to pass boss and name.
in the inherited class Company, you must send super(boss,name) the received parameters and not the null strings defined in class MB