How to change and get objects from aother class without declaring it? - java

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");

Related

Creating subclass object in an array which type of superclass in java

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".

Access variables from other classes

I have a class that is receiving input from users. Then the results are parsed and stored in this class I placed below. Then there is a separate class that is taking what is stored in the class below and creating something with it. I would post all of the classes, but there are just too many lines of code. I have placed below the exact class I have a question on (minus other variables of the same type for simplicity)
I would like to know if there is a way to access variables from an abstract class within another class. Here is my abstract class:
public abstract class ParsResults {
public String AnsName;
public String AnsType;
}
Then I have another class that needs these variables. Im just not sure how to approach it. Thanks in advance.
There is absolutely no way accessing instance variables of instances of abstract classes, since they can not have instances.
Please do not make instance variables public, make them private and provide getters and setters.
Your instance variables should start with a lowercase letter.
If you have an instance of a concrete subclass of ParsResults, you can access its values using the getters (see point 2.).
To share variables between classes, there are three ways:
public class Human {
// instance variables
public String name;
public int age;
//constructor, creates an instance of the Human class.
public Human(String s, int i){
name = s;
age = i;
}
}
in this case, your instance variables are public.
so in another class, when you create a instance of a Human class by calling:
Human aHuman = new Human(tom, 25);
then you can access the two instance variables directly. you can get its value by using:
String theHumanName = aHuman.name;
and you can set its value(change it) by using:
aHuman.name = "mike";
the two above lines will only work if your variables are public.
the reason you should make them private is to keep the values from being changed from outside the class. So if they are private then you create get and set methods, depending on the need.
Here is how it should be done:
public class Human {
// instance variables
private String name;
private int age;
//constructor, creates an instance of the Human class.
public Human(String s, int i){
setName(s);
setAge(i);
}
/**
* #return the name
*/
public String getName() {
return name;
}
/**
* #param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* #return the age
*/
public int getAge() {
return age;
}
/**
* #param age the age to set
*/
public void setAge(int age) {
this.age = age;
}
}
now from outside the class, you can call:
String theHumanName = aHuman.getName(); // this a method call, therefore you must have the parentheses
and you can set its value(change it) by using:
aHuman.setName("mike");
You have to instatiate that class, but you can't instantiate an abstract class.
So first create a not abstract class witch extends ParsResults, then instantiate this new class and in your main you can see the variables like this:
public class NewClass extends ParsResults {
//...
}
public static void main(String [] args){
NewClass nc = new NewClass();
// ...
System.out.println(nc.Name);
}

ArrayList of class as parameter

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
....
}

How do I make variables in a Main accessible to other classes?

For example I have a MovieDatabase class that contains a list of Movie objects. In my main code, I initialize all the objects in the MovieDatabase. However I wish to call this MovieDatabase in another class to access the library. How would I do this?
Do I add in get methods in my main code and return it? Or is there another way (eg. changing the list of objects to protected/public?)
Thanks!
Code's supposed to be 3 seperate classes, Main, MovieDatabase & Movie.
An instance of movieDatabase is initialized in Main. Upon construction, it calls loadMovieList() and populates the list from a text file. However I wish to call the same instantiation of movieDatabase from another class in order to access the movies, so that I do not have to repeat the loading.
public class Main {
public static void main(String[] args) {
MovieDatabase movieDatabase = new MovieDatabase();
}
public class MovieDatabase {
ArrayList<Movie>movieList = new ArrayList<Movie>();
String fileAddress = "D:/Users/Mine/School/Java/CZ2002_Assignment/src/MovieDatabase/movieDatabase.txt";
public MovieDatabase()
{
numOfMovie=0;
loadMovieList();
}
public int getNumOfMovie() {
return numOfMovie;
}
public void addMovieToList(Movie movie) {
movieList.add(movie);
numOfMovie++;
}
public Movie selMovieByID(int movieID) {
int index=-1;
for (Movie m : movieList) {
index++;
if (m.getMovieID() == movieID)
break;
}
return selMovieByIndex(index);
}
public Movie selMovieByIndex(int index) {
return movieList.get(index);
}
public void loadMovieList()
{
//loads through text file
addMovieToList(new Movie(tempMovie));
System.out.println("Movie Database loaded");
}
public class Movie{
private int movieID;
private String movieName;
private int movieDuration; //in minutes;
private String movieRating; //G; PG; PG13; NC16; M18; R21;
private boolean has3D;
private boolean status;
}
If you have a class that depends on a NameLibrary, you should inject it via the constructor or a set method.
Firstly, its difficult to assess what issues you truly have without any code to show us.
However you mention main method, as in
public static void main(String args[]){};
this main method is designed specifically to run the application, your compiler needs that specific method, it is not designed to be used as an accessor method
e.g.
public int getValue(){
return value;}
this is not the only reason you can't access the main method variable. main doesn't have a return type (due to the use of void) plus the idea of SCOPE (each method has a scope, any method that contains a variable can see that variable, but nothing outside of it can directly see it without a return type) you use scope to limit what can be accessed or what cannot be accessed outside of the methods or classes (thats why class variables usually will have private, in order to limit accessibility)
Create a getter-method which returns the list inside your NameLibrary. if your other class extends from NameLibrary you can call this getter-method with the object reference to your NameLibrary class.
If you want int x to be accessible from other classes, you write:
public class myClass{
public int x = 0;
}
To access it from other classes, you simply write:
myClass.x ... (do something)

Change value from another form java

I have a main form (RandomSend) and another form called (_user)
in the randomsend form I declare a public static variable:
public class RandomSend extends javax.swing.JFrame {
......
public static String userGender; // this variable I want to change from another form (_user)
....
}
and in the RandomSend class I declared _user instance that try to change userGender value
_user setGender = new _user();
setGender.setModalExclusionType(ModalExclusionType.APPLICATION_EXCLUDE);
setGender.setAlwaysOnTop(true);
setGender.setVisible(true);
In the _user form (class) I trying to change userGender vale:
public class _user extends javax.swing.JFrame {......
....
RandomSend.userGender="male";
....}
when I check the value from within _user , the value of RandomSend.userGender is "male"
but from my main form the value is null...
new new
My attempt According to answer number 1
public class RandomSend extends javax.swing.JFrame {
/**
*
*/
private static String userGender;
.....
.....
// show dialogbox to select gender...
_user setGender = new _user();
setGender.setModalExclusionType(ModalExclusionType.APPLICATION_EXCLUDE);
setGender.setAlwaysOnTop(true);
setGender.setVisible(true);
....
....
// setter
public static void setUserGender(String gender)
{
if(gender.toLowerCase().equals("female") ||gender.toLowerCase().equals("male"))
userGender = gender;
else userGender= "Unknown!!";
}
//getter
public static String getUserGender()
{
return userGender;
}
and in the other class (frame) :
public class _user extends javax.swing.JFrame {
....
....
RandomSend.setUserGender("male");
..
..
..
}
but the Randomsend.userGender doesn't change!
You make changes to an objects member values via the use of getter and setter functions that you define on that object. To use your example you'd end up with something like:
public class RandomSend extend javax.swing.JFrame {
// This should be preferred for values that can mutate (non-final) to prevent
// modification without the owning class being alerted the value is changing
private static String userGender;
public static void setUserGender(String value) {
userGender = value;
}
public static String getUserGender() {
return userGender;
}
}
Using this example you would change the value by calling RandomSend.setUserGender("male") and you would read this value by calling RandomSend.getUserGender().
Some Additional Notes
I just wanted to point out some additional things that I noticed about your sample. Using static values in the manner that you are is not necessarily the best idea. You're locking the use of the class down in the wrong way. You should maintain an instance of a User class or some other kind of class that manages information specific to a user, such as gender. By managing an instance instead of static values on a class you're making it easier for you to handle other users within the application if that need ever rose up. If you are sure you never need to support more than the current user, then you can still use instances but implement it with a singleton pattern.
That would look something like:
public class SingletonExample {
private static SingletonExample instance = null;
// Declared private to prevent new SingletonExample
// outside of this class
private SingletonExample {}
public static SingletonExample getInstance() {
if (instance == null) {
instance = new SingletonExample();
}
return instance;
}
}
You would use this class by fetching an instance like SingletonExample.getInstance() and then operate on that instance. Using this methods guarantees that in all points in your project you're accessing the same instance of the same object making "global" in a sense.
Another note I would like to make is try and use final values or better yet, an enum instead of strings for things like gender which you will most likely use as values. I say this because in order to properly compare genders you have to do:
if (RandomSend.userGender.equals("male")) {
// ...
}
If you instead created a Gender class with constants like:
public Gender {
public static final int MALE = 1;
public static final int FEMALE = 2;
}
And comparisons (provided value changes in the proper classes)
if (RandomSend.userGender == Gender.MALE) {
// ...
}
And no more wasted string literals being passed around. This is such a good idea that Java has an entire construct unique to providing this solution called enums. You would define a Gender enum like so:
public enum Gender {
MALE,
FEMALE;
}
And then you declare you userGender as a Gender value and your comparisons are the same as if you built the enum yourself from a class with constant values. These changes can, in the long run, make your projects more manageable and easier to maintain.

Categories