How can I pull variables from one java file to another? - java

I'm at very early stages of learning java.
I currently have one file which has 900 lines of code, which is not good.
I would like to separate my Java file into separate java files which I could "link"
together in some way.
I used to work a lot with CSS, and there it was insanely easy to pull some stylesheets in with the #import.
Would there be a way to "copy" all variables from a file to a different one, the #import way? If I had my array "p" defined in the separate file, could I just #import this file into my main file in a way where I could just try to print p and it would do it?
Thanks a lot in advance!

You cannot split a single class into several different source files. Each source file in Java corresponds to exactly one class. (A class can contain its own inner classes, but that's an unnecessary distraction at your stage!)
You can arrange things so that a member of one class is visible to members of other classes, by giving it the public or default access modifier.
See In Java, difference between default, public, protected, and private

You will probably want to read up about Object Oriented Programming. There are lots of tutorials on Oracle's website. http://docs.oracle.com/javase/tutorial/java/javaOO/index.html
In your case, you can split your classes up to store your array in one class and access it from another class. Something like this:
Here's the class that contains the array:
public class ClassA
{
public int [] arr = {1,2,3,4};
public int [] getArr()
{
return arr;
}
}
Here's the class that accesses the array:
public class ClassB
{
public void printArray(ClassA classB)
{
// access the array through a "getter" (recommended)
System.out.println(Arrays.toString(classB.getArr()));
// you can also access the array directly since it is a public variable
System.out.println(Arrays.toString(classB.arr));
}
public static void main(String [] args)
{
ClassB a = new ClassB();
ClassA b = new ClassA();
a.printArray(b);
}
}
If your classes are in different packages, you include an import statement at the top of the file like:
import packageName.ClassA;

You might want to consider splitting the class if you think it has low cohesion. Take a look at SOLID
Some of the principles listed here might help you break down the class in to smaller manageable highly cohesive units.

I imagine you have something like this currently where everything is in one big class:
public class Main1 {
private String street;
private String city;
public Main1(String street, String city) {
this.street = street;
this.city = city;
}
private void printAddress() {
System.out.println(street);
System.out.println(city);
}
public static void main(String[] args) {
Main1 ex = new Main1("1 Main street", "Springfield");
ex.printAddress();
}
}
As a first step I would move some of the data out of your class into another class, grouping like data together (in this case it's obviously an Address) and then reference that class in your original class, maybe:
class Address {
private String street;
private String city;
public Address(String street, String city) {
this.street = street;
this.city = city;
}
public String getCity() {
return city;
}
public String getStreet() {
return street;
}
}
public class Main {
private void printAddress(Address address) {
System.out.println(address.getStreet());
System.out.println(address.getCity());
}
public static void main(String[] args) {
Main ex = new Main();
Address address = new Address("1 Main street", "Springfield");
ex.printAddress(address);
}
}
After that you might notice that some of the functionality might also logically belong on the class you just pulled out and you can provide methods on the new class to provide that functionality:
class Address {
private String street;
private String city;
public Address(String street, String city) {
this.street = street;
this.city = city;
}
public String formattedAddress() {
return street + "\n" + city;
}
}
public class Main {
public static void main(String[] args) {
Main ex = new Main();
Address address = new Address("1 Main street", "Springfield");
System.out.println(address.formattedAddress());
//ex.printAddress(address);
}
}

Related

Creating a Person class with Name and Address subclasses?

For an assignment I am designing a simple "chatroom" system. It is very rudimentary and simply involves objects of a Person class sending messages to each other through a separate Chatroom object.
Below is my Person class (did not include getter/setter methods for sake of brevity).
public class Person {
protected String firstName;
protected String lastName;
protected String message;
Person(String fn, String ln)
{
firstName = fn;
lastName = ln;
}
public void sendMessage(String msg, Person rec)
{
rec.receiveMessage(msg);
}
public String receiveMessage(String msg)
{
message = msg;
}
}
these Person objects are instantiated and send messages to each other through the Chatroom class using the sendMessage method.
Now I am supposed to design a larger Person class, into multiple classes by adding Address, Name and Contact classes to the multi class system. The problem is I don't know how to associate these classes with the Person class. At first I tried to make an inheritance relationship with the Name class adding the middleInitial field, but i dont see the utility in this.
public class Name extends Person {
protected String middleInitial;
Name(String fn, String ln) {
super(fn, ln);
}
public static void main(String args[])
{
}
public String getMI()
{
return middleInitial;
}
public void setMI(String mi)
{
middleInitial = mi;
}
I don't understand the need for these separate classes, couldn't all this information be stored in the Person object? Can someone help me understand a way to design these classes separately but all be part of the Person object?
In this case - yes name should be part of Person. In OOP (Object Oriented Programming) "extends" means "is-a". In your case "Name" is definitely not "is-a" Person. Person should contain name - so "Name" should be a property and not "extend" person.

Add new class variable java + getter/setter method without editing class

Is there any way to create new class variable or method in java without editing class java
Example:
I have class Person
public class Person {
private String name;
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
and in main class I process like this:
Person personData = new Person();
personData.setName("My Name");
personData.setAddress("Address");
List<Person> person = new ArrayList<Person>();
person.add(personData);
I want to add new person variable in List
and have setNo(); and getNo();
So list index[0] have person with property No, Name, And Address without editing the class Person first.
There is no way in Java to add methods to a class without changing the class source code.
The only possibility you have is to either extend from this class (by creating a subclass that inherits from Person) or to create a completely new class that contains a Person object.
The first concept is called inheritance; the second one composition. You can find a discussion of "one versus the other" here for example.
But in essence the answer: step back and read a good book about Java.
I would probably create another class which extends Person.
import java.util.ArrayList;
import java.util.List;
public class PersonNo extends Person {
public static void main(String[] args) {
PersonNo personData = new PersonNo();
personData.setName("My Name");
personData.setAddress("Address");
List<PersonNo> person = new ArrayList<>();
person.add(personData);
}
public void setNo(int n) {
this.no = n;
}
public int getNo() {
return this.no;
}
private int no;
}
This requires you to change the List type to "PersonNo" and to add "PersonNo"s, but it will give you the functionality you need. If you create the List with "Person", you can add "PersonNo"s but you will not have the setNo/getNo unless you cast the "Person" into a (PersonNo).

How to use encapsulation?

After I read online E-book.They said the benefit of encapsulation is "A class can change the data type of a field and users of the class do not need to change any of their code.". I don't understand what they say in the point. What is the main meaning of the point? Can you give an example,please?
Let's take a simple class Vehicles, which maintains a list:
public class Vehicles {
private ArrayList<String> vehicleNames;
Vehicles() {
vehicleNames = new ArrayList<String>();
}
public void add(String vehicleName) {
vehicleNames.add(vehicleName);
}
}
This will be used by a client in the following way:
public class Client {
Public static void main(String []args) {
Vehicles vehicles = new Vehicles();
vehicles.add("Toyota");
vehicles.add("Mazda");
}
}
Now if Vehicles changes its internal private vehicleNames field to be a LinkedList instead, Client would be unaffected. That is what the book is talking about, that the user/client does not need to make any changes to account for the changes in the class due to encapsulation.
Encapsulation is really important in Object-Oriented Programming. Using encapsulation, you can hide information from users who use your class library/API.
"And why do I need to hide stuff from the users?", you ask. There are a lot of reason. One main reason is that some users who are naughty or just don't know what the API is doing may mess with your classes and stuff. Let me give you an example.
Suppose you have a class here:
public class Computer {
public int coreCount;
}
As you can see here, coreCount is declared public. That means all other classes can access it. Now imagine a naughty person do this:
Computer myPC = new Computer ();
myPC.coreCount = 0;
Even fools can tell that this doesn't make any sense. It might also affect your program's other stuff. Imagine you want to divide by the core count. An Exception would occur. So to prevent this, we should create setters and getters and mark the field private.
C# Version:
public class Computer {
private int coreCount;
public int CoreCount {
get {return coreCount;}
set {
if (value > 0)
coreCount = value;
}
}
}
Java version
public class Computer {
private int coreCount;
public int getCoreCount () {return coreCount;}
public void setCoreCount (int value) {
if (value > 0)
coreCount = value;
}
Now no one can set the core count to non-positive values!
Here's an example of encapsulation. Say we have a Person class, like so
class Person {
private String name;
private String email;
public String getName() { return this.name; }
public String getEmail() { return this.email; }
public void setName(String name) { this.name = name; }
public void setEmail(String email) { this.email = email; }
}
And at some point, we decide we need to store these values not as a couple strings, but as a HashMap (for some reason or another).
We can change our internal representation without modifying the public interface of our Person class like so
class Person {
HashMap<String, String> data;
public Person() {
this.data= new HashMap<String, String>();
}
public String getName() { return this.data.get("name"); }
public String getEmail() { return this.data.get("email"); }
public void setName(String name) { this.data.put("name", name); }
public void setEmail(String email) { this.data.put("email", email); }
}
And from the client code perspective, we can still get and set Strings name and email without worrying about anything else.

How do I use Java getters and setters with a collection of data without explicitly typing out the attributes for each item?

I am very new to Java and to programming in general, and I have an assessment to complete where I load employees (with name, age, and department attributes; department can be only one of four enumerated values) into a program that will sort them by age and tell if the age is a prime number. The assignment requires Company, Department, and Employee classes. I am confident that I can figure out age/prime components — I know how to google for algorithms. What I am struggling with is putting all the discrete pieces into a cohesive whole.
Here is what I have so far. I've put in one employee, but the way I'm doing it seems completely inelegant and inefficient. I am sure there is a better way, but I've hit a mental block.
EDIT: as was pointed out below, I was unclear. What I am asking help with is populating the data structure.
Company class:
public class Company {
static Employee one = new Employee();
public static void main(String[] args) {
one.setName("Counting Guru");
one.setAge(55);
one.setDepartment(DepartmentList.ACCOUNTING);
}
}
DepartmentList class:
import java.util.EnumMap;
import java.util.Map;
import java.util.Set;
public enum DepartmentList {
ACCOUNTING, MARKETING, HUMANRESOURCES, INFORMATIONSYSTEMS;
public static void main(String[] args) {
Map<DepartmentList,String>
enumMap=new EnumMap<DepartmentList,String>(DepartmentList.class);
enumMap.put(DepartmentList.ACCOUNTING, "Accounting");
enumMap.put(DepartmentList.MARKETING, "Marketing");
enumMap.put(DepartmentList.HUMANRESOURCES, "Human Resources");
enumMap.put(DepartmentList.INFORMATIONSYSTEMS, "Information Systems");
Set<DepartmentList> keySet = enumMap.keySet();
for (DepartmentList department : keySet) {
String value = enumMap.get(department);
System.out.println("ENUMMAP VALUE:"+value);
}
}
}
Employee class:
public class Employee {
String empName;
int empAge;
DepartmentList empDept;
Employee() {
}
public String getName() {
return empName;
}
public void setName(String name) {
this.empName = name;
}
public int getAge() {
return empAge;
}
public void setAge(int age) {
this.empAge = age;
}
public DepartmentList getDepartment() {
return empDept;
}
public void setDepartment(DepartmentList department) {
this.empDept = department;
}
public Employee(String empName, int empAge, DepartmentList empDept){
}
}
I also have a Department class, but it's currently empty.
Am I on the right track? Can someone give me a nudge? Thank you!
Don't hard-code the data inside the Java program. Put the data in a file and write methods to load the data.
If you MUST hardcode the data in the program, use something like this sample:
public class Employee
{
String name;
int age;
public Employee(String name, int age)
{
this.name = name;
this.age = age;
}
// getters, setters, etc.
}
In the main program
private static Employee[] empData =
{
new Employee("John Smith", 50),
new Employee("Fred Jones", 25),
.
.
.
};
Now you have a static array of Employee objects that you can "load" into your data structure.
If you're asking if there is something like a property in Java, no, there isn't (at least not yet).
If you're asking how to populate your objects something like an IOC container, like Spring, would be a better choice.
Now as it comes to your code you have two main methods in two different classes. Only one will be called. If you want to create a static instance you will be better do
static Employee one = new Employee("Counting Guru", 55, DepartmentList.ACCOUNTING);
or
static Employee one = new Employee();
static {
one.setName("Counting Guru");
one.setAge(55);
one.setDepartment(DepartmentList.ACCOUNTING);
}
When it comes to the enum then you'll better define a constructor for it
public enum DepartmentList {
ACCOUNTING("Accounting"), MARKETING("Marketing");
private String displayName;
public DepartmentList(String displayName) {
this.displayName = displayName;
}
public String getDisplayName() {
return diplayName;
}
}
In the Employee constructor you need to assign the field values to the ones received as arguments.

String Array object in Java

I am trying to print the first element on the two arrays in my Athlete class, country and name. I also need to create a object that simulates three dive attemps an athlete had (that is initially set to zero). I am new to OOP and I dont know how to go abouts doing this in my main... as far as constructors go. This is what i have done so far...
this is the main:
import java.util.Random;
import java.util.List;
public class Assignment1 {
public static void main(String[] args) {
Athlete art = new Athlete(name[0], country[0], performance[0]);
}
}
I just really am not sure what to do...
And this is the class with the arrays.
import java.util.Random;
import java.util.List;
public class Athlete {
public String[] name = {"Art", "Dan", "Jen"};
public String[] country = {"Canada", "Germant", "USA"};
//Here i would like to create something that would be representing 3 dive attemps (that relate to dive and score. eventually.)
Athlete(String[] name, String[] country, Performance[] performance) {
this.name = name;
this.country=country;
this.performance=performance;
}
public Performance Perform(Dive dive){
dive.getDiveName();
return null;
}
public String[] getName() {
return name;
}
public void setName(String[] name) {
this.name = name;
}
public String[] getCountry() {
return country;
}
public void setCountry(String[] country) {
this.country = country;
}
}
thanks in advance for any help and input!
btw there is other classes too, just not relevant atm..
First, as for your Athlete class, you can remove your Getter and Setter methods since you have declared your instance variables with an access modifier of public. You can access the variables via <ClassName>.<variableName>.
However, if you really want to use that Getter and Setter, change the public modifier to private instead.
Second, for the constructor, you're trying to do a simple technique called shadowing. Shadowing is when you have a method having a parameter with the same name as the declared variable. This is an example of shadowing:
----------Shadowing sample----------
You have the following class:
public String name;
public Person(String name){
this.name = name; // This is Shadowing
}
In your main method for example, you instantiate the Person class as follow:
Person person = new Person("theolc");
Variable name will be equal to "theolc".
----------End of shadowing----------
Let's go back to your question, if you just want to print the first element with your current code, you may remove the Getter and Setter. Remove your parameters on your constructor.
public class Athlete {
public String[] name = {"Art", "Dan", "Jen"};
public String[] country = {"Canada", "Germany", "USA"};
public Athlete() {
}
In your main method, you could do this.
public static void main(String[] args) {
Athlete art = new Athlete();
System.out.println(art.name[0]);
System.out.println(art.country[0]);
}
}
Currently you can't access the arrays named name and country, because they are member variables of your Athelete class.
Based on what it looks like you're trying to do, this will not work.
These arrays belong in your main class.
Your attempt at an athlete class seems to be dealing with a group of athletes, which is a design fault.
Define a class to represent a single athlete, with fields that represent the athlete's attributes:
public class Athlete {
private final String name;
private final String country;
private List<Performance> performances = new ArrayList<Performance>();
// other fields as required
public Athlete (String name, String country) {
this.name = name;
this.country = country;
}
// getters omitted
public List<Performance> getPerformances() {
return performances;
}
public Performance perform(Dive dive) {
// not sure what your intention is here, but something like this:
Performance p = new Performance(dive, this);
// add new performance to list
performances.add(p);
return p;
}
}
Then your main method would use ti like this:
public class Assignment1 {
public static void main(String[] args) {
String[] name = {"Art", "Dan", "Jen"};
String[] country = {"Canada", "Germant", "USA"};
Dive[] dive = new Dive[]{new Dive("somersault"), new Dive("foo"), new Dive("bar")};
for (int i = 0; i < name.length; i++) {
Athlete athlete = new Athlete(name[i], country[i]);
Performance performance = athlete.perform(dive[i]);
// do something with athlete and/or performance
}
}
}
I think you are a little messed up with what you doing.
Athlete is an object, athlete has a name, i has a city where he lives.
Athlete can dive.
public class Athlete {
private String name;
private String city;
public Athlete (String name, String city){
this.name = name;
this.city = city;
}
--create method dive, (i am not sure what exactly i has to do)
public void dive (){}
}
public class Main{
public static void main (String [] args){
String name = in.next(); //enter name from keyboad
String city = in.next(); //enter city form keybord
--create a new object athlete and pass paramenters name and city into the object
Athlete a = new Athlete (name, city);
}
}
public static void main(String[] args) {
public String[] name = {"Art", "Dan", "Jen"};
public String[] country = {"Canada", "Germant", "USA"};
// initialize your performance array here too.
//Your constructor takes arrays as an argument so you need to be sure to pass in the arrays and not just objects.
Athlete art = new Athlete(name, country, performance);
}
First off, the arrays are pointless, let's get rid of them: all they are doing is providing values for mock data. How you construct mock objects has been debated ad nauseum, but clearly, the code to create the fake Athletes should be inside of a unit test. I would use Joshua Bloch's static builder for the Athlete class, but you only have two attributes right now, so just pass those in a Constructor. Would look like this:
class Athlete {
private String name;
private String country;
private List<Dive> dives;
public Athlete(String name, String country){
this.name = name;
this.country = country;
}
public String getName(){
return this.name;
}
public String getCountry(){
return this.country;
}
public String getDives(){
return this.dives;
}
public void addDive(Dive dive){
this.dives.add(dive);
}
}
Then for the Dive class:
class Dive {
private Athlete athlete;
private Date date;
private double score;
public Dive(Athlete athlete, double score){
this.athlete = athlete;
this.score = score;
this.date = new Date();
}
public Athlete getAthlete(){
return this.athlete;
}
public Athlete getAthlete(){
return this.athlete;
}
public Athlete getAthlete(){
return this.athlete;
}
}
Then make a unit test and just construct the classes, and manipulate them, make sure that they are working. Right now they don't do anything so all you could do is assert that they are retaining the Dives that you are putting in them. Example:
#Test
public void testThatDivesRetainInformation(){
Athlete art = new Athlete("Art", "Canada");
Dive art1 = new Dive(art, 8.5);
Dive art2 = new Dive(art, 8.0);
Dive art3 = new Dive(art, 8.8);
Dive art4 = new Dive(art, 9.2);
assertThat(art.getDives().size(), is(5));
}
Then you could go through and add tests for things like, making sure that you can't construct a dive without an athlete, etc.
You could move construction of the athletes into the setup method of the test so you could use it all over the place. Most IDEs have support for doing that with a refactoring.

Categories