Java, how to merge smaller classes via 1 big class? - java

Imagine having the following classes:
Head
Torso
Hands
Legs
that I would like to keep but link them via a new class Human. This is what their codes look like:
package myEntities;
public class Head {
private float headSize;
Head(float headSize) {
this.headSize = headSize;
}
public static void main(String[] args) { }
public float[] getHeadSize() {
return headSize;
}
}
repeated the same for the other 3 parts except for the name. If I wanted to make a human class, how would it look like? I'm thinking something like this but this seems too repetitive:
package myEntities;
public class Human {
private Head headObject = new Head(variable1);
private Torso torsoObject = new Torso(variable2);
private Leg rightLegObject = new Leg(variable3);
Human(float variable1, float variable2, float variable3) {
}
public static void main(String[] args) { }
And this way gives an error of not being able to resolve variable1 and the rest of the variables.

First, in your human class, the constructor should be a Human constructor (not a Zombie - Zombie could be a superclass, a subclass, or a completely separate class)
public class Human {
Human(float variable1, float variable2, float variable3) {
}
}
Second, you need to declare the object members like you are doing, but initialize them in your constructor
Human {
private Head headObject;
private Torso torsoObject;
private Leg rightLegObject;
public Human (float variable1, float variable2, float variable3) {
headObject = new Head(variable1);
torsoObject = new Torso(variable2);
rightLegObject = new Leg(variable3);
}
}

Related

Getting Variables From Java constructor

I'm new to Java programming, sorry if this is a dumb question.
I find it hard to word this question properly, but I have an assignment to create a aircraft class that can make aircraft land, takeoff etc. And need to test it using Testclass. When the new object are entered it automatically assigns a unique ID to the aircraft in the constructor.
I can do this using a instance method fine as it has a return value which is returned to to Testclass. The question wants me to do this in the constructor itself, however, the constructor never returns anything. So the variable never gets sent to the Testclass. I clearly am not understanding OOP properly. Even when I try to just use a getter method to get the ID created in the constructor it gives me the initialized variable before the the constructor has worked on this. This is the code I have so far and its completely wrong I know but if someone could point me in the right direction or tell me how to word this question better it would be a massive help.
// I need to enter 3 aircraft into the system in the testclass
public class Aircraft {
private int aircraftID;
private static int lastID;
private String airportcode;
private int ID = 100;
private int count;
public Aircraft(int a, int b, int c){
// Constructor
// Assign ID
this.ID = a;
lastID = ID;
ID++;
this.ID =b;
lastID = ID;
ID++;
}
}
OK, you want to create an Aircraft that has an automatically-assigned unique identifier, and can take off and land. That implies you need a field for tracking the identifier, a field for tracking whether it's in the air (or not), and methods for the take off and land operations. You also need a static field for generating the unique identifiers. (Note that this implementation isn't thread safe.)
private class Aircraft {
private static int staticId = 0;
private int uniqueId = 0;
private boolean onGround = true; // Aircraft start on the ground in this implementation
public Aircraft(){
this.uniqueId = staticId; // putting this line first makes uniqueId zero-indexed in effect
staticId++;
}
public void land(){
onGround = true;
}
public void takeoff(){
onGround = false;
}
public boolean isFlying(){
return !onGround; // If it's not on the ground, it's flying
}
public int getUniqueId(){
return uniqueId;
}
}
Unit tests checks all of the methods and expected functionality of the class in question:
import org.junit.Test;
import static org.junit.Assert.*;
import Aircraft;
class Testclass {
private final Aircraft aircraft = new Aircraft();
#Test
public void hasId(){
aircraft.getUniqueId() >= 0;
}
#Test
public void canLand(){
assertTrue(aircraft.land());
}
#Test
public void canTakeOff(){
assertTrue(aircraft.takeOff());
}
#Test
public void checkFlightOperationsAreTrackedCorrectly(){
aircraft.land();
assertFalse(aircraft.isFlying());
aircraft.takeOff();
assertTrue(aircraft.isFlying());
}
}
As pointed out a constructor does not return anything (the simplified version is that with new it returns an object instance). I am kinda guessing at what you are trying to acomplish, but I'll have a go anyways. It seems to me that you are trying to cram the construction of 3 objects into one constructor - which is why your constructor has 3 parameters. Also you are playing havoc with the IDs.
I have removed all the variables that I didnt quite understand, leaving only ID that increments with each instantiated Aircraft. The #Override is mainly just for show.
public class Aircraft {
private int aircraftID;
private static int lastID = 0;
#Override
public String toString(){
return "Aircraft_" + this.aircraftID;
}
public Aircraft() {
lastID++;
this.aircraftID = lastID;
}
}
I took the liberty and wrote the TestClass just to see if we have the same thing in mind. Again the printAircraft() method is for show.
public class TestClass {
private List<Aircraft> aircrafts;
public TestClass(){
aircrafts = new ArrayList<>();
}
public void addAircraft(Aircraft a){
aircrafts.add(a);
}
public void printAircraft(){
Iterator<Aircraft> it = aircrafts.iterator();
while(it.hasNext()){
System.out.println(it.next().toString());
}
}
}
and to test it, we create and instance of TestClass add 3 Aircraft instances and print out the contents
public static void main(String[] args) {
TestClass tc = new TestClass();
tc.addAircraft(new Aircraft());
tc.addAircraft(new Aircraft());
tc.addAircraft(new Aircraft());
tc.printAircraft();
}
This would be the case if you are to write the TestClass. If that is given, it would help to know what it looks like - maybe that would help us understand better.

Java: Inmutable static variable, possible?

I have a class with this, it's an example code, not the real code
private static String className;
public static Wish getInstance(Class<?> clazz) {
if(wish == null)
wish = new Wish();
className = clazz.getName();
return wish;
}
Many classes use this Wish class, then each class should "say" a wish with the className passed in the getInstance method.
Then I have something like this
public class Boy {
private Wish w = Wish.getInstance(Boy.class);
//at this moment the static variable take "com.package.Boy" value
....
}
Another classs
public class Girl {
private Wish w = Wish.getInstance(Girl.class);
//at this moment the static variable take "com.package.Girl" value
....
}
When everybody start to say their wishes, example
public class WishesDay {
private Girl g;
private Boy b;
public void makeYourWish() {
g = new Girl(); //get the com.package.Girl value
b = new Boy(); //get the com.package.Boy value
//sample output "com.package.Boy wants A pink house!"
g.iWish("A pink house!"); // the boys don't want this things :(
b.iWish("A spatial boat!");
}
}
I know that each object have the same copy o the Wish class and the static variable className change when each object (Girl, Boy) call the Wish.getInstance(Class<?> clazz) method.
How can I use a static variable (I want avoid to instantiate the Wish class) and keep the correct value for the variable className.
Can I make this with a static variable? or the solution is to instantiate (no static variable)
For example, log4j has the Logger class, I want to make the same thing with the class name.
You'll have to make your constructor private if you want to avoid instantiate the Wish class and make the className not static.
public class Wish {
String className;
private Wish(String className){
this.className = className;
}
public static Wish getInstance(Class<?> clazz) {
String className = clazz.getName();
return new Wish(className);
}
public String getClassName() {
return className;
}
}
package com.test;
public class WishesDay {
private Girl g;
private Boy b;
public void makeYourWish() {
g = new Girl(); //get the com.package.Girl value
b = new Boy(); //get the com.package.Boy value
//sample output "com.package.Boy wants A pink house!"
g.iWish("A pink house!"); // the boys don't want this things :(
b.iWish("A spatial boat!");
}
public static void main(String[] args) {
WishesDay wd = new WishesDay();
wd.makeYourWish();
//outputs com.test.Girl wants A pink house!
//com.test.Boy wants A spatial boat!
}
}

How can I share instantiated objects between methods?

I have:
public class HFSim extends ApplicationTemplate
{
private static class AppFrame extends ApplicationTemplate.AppFrame
{
void setBuoy()
{
//code
Position buoypos=Position.fromDegrees(buoylat, buoylon);
}
void setVehicle()
{
//code
Position vehiclepos=Position.fromDegrees(lat, lon, elev);
}
double findDistance()
{
//find distance between marker (vehicle) and a buoy
Earth earth= new Earth();
double radius = earth.getEquatorialRadius();
double distancebetween=LatLon.ellipsoidalDistance(buoypos, vehiclepos, radius, 6356752.3);
return distancebetween;
}
How can I use the objects buoypos and vehiclepos in the setBuoy and setVehicle methods in the findDistance() method?
You have two clearcut options here:
Make buoypos and vehiclepos instance variables, or..
Provide more descriptive names for setVehicle() and give it a Position return type.
Option 1 would look like this:
...classname...
{
private Position vehiclePosition;
private Position bouyPosition;
public void setVehiclePosition()
{
this.vehiclePosition = ....
}
}
Option 2 would look like this:
...classname...
{
public Position createVehiclePosition()
{
vehiclePosition = ....
return vehiclePosition.
}
}
Finally, you would use them as either:
...classname...
{
public double findDistance()
{
...this.vehiclePosition...
or
Position vehiclePos = this.createVehiclePosition();
}
}
The option you choose is highly dependent on how the class is supposed to behave.
Use variables with the class scope. This essentially means
///outside of a method but within the class you'll want to set:
private this.bouypos = new Position;
private this vehiclepos = new Position;
//method1 {
Position this.buoypos=Position.fromDegrees(buoylat, buoylon);
//method2 {
Position this.vehiclepos=Position.fromDegrees(lat, lon, elev);
//method3 calls things set in method1 & 2
findDistance(){
//code
double distancebetween=LatLon.ellipsoidalDistance(this.buoypos, this.vehiclepos, radius, 6356752.3);
}
Make the findDistance method take two Positions as parameters
double findDistance(Position buoypos, Position vehiclepos){
}

Calling a method from JFrame from another class

I am currently making a terrain generator, everything works fine in one class but I am going to be expanding my application.
Currently I have a JFrame class which holds everything, generating the terrain, painting the terrain, finding locations etc.
I want to add another class that will generate the terrain but when I create this class I need to access fields from the main JFrame class and when I do I get a stack overflow error - here is my code.
public class Simulator extends Applet
{
//fields
public Simulator()
{
grid = new int[100][100];
inhabGrid = new boolean[grid.length][grid.length];
gridSize = grid.length - 1;
dist = grid.length;
TerrainGenerator gen = new TerrainGenerator();
setSize(dist,dist);
seedGrid();
findInhabLocation();
printGridToConsole();
}
public void paint(Graphics g)
{
//panting the grid
}
public void seedGrid()
{
//seeding
}
public boolean generateTerrain(int x1,int y1, int x2, int y2)
{
//terrain generator
}
public boolean mouseUp(Event evt, int x, int y)
{
seedGrid(); //Create a new map
findInhabLocation();
repaint();
printGridToConsole();
return true;
}
public boolean keyEvents(Event evt, int x, int y)
{
seedGrid(); //Create a new map
findInhabLocation();
repaint();
printGridToConsole();
return true;
}
public void findInhabLocation()
{
//find best inhabitant location
}
public int locateWater(int x, int y)
{
//finding closest water
}
public int locateJungle(int x, int y)
{
//finding closest jungle
}
}
}
That works fine in its own class but when I create a class for example:
public class TerrainGenerator
{
Simulator sim = new Simulator();
}
I know this has something to do with the constructor and it's something silly I am doing, what would be the best way of splitting up this app into classes, for example terrain generator, inhabitants etc
For example I want to be able to call a method from the 'TerrainGenerator' class and call i.e. terrainGenerator.generateTerrain
Your TerrainGenerator creates a Simulator object and vice versa, hence you'll end up with infinitely many objects (but at some point the stack is full and a stack overflow exception is thrown instead...)
Instead of creating a new Simulator in your TerrainGenerator, you should pass a reference to your current Simulator (well, actually, that is not a great design either, but I'm not gonna confuse you with the problems of circular references).
Heuster answer is correct, furthermore, I think you could take look at MVC to help you organize your classes.
Depending which should be the parent, you can pass in the instantiated class to the other, ie;
private final TerrainGenerator gen; //if you need to save this.
public Simulator(TerrainGenerator terrainGenerator)
{
this.gen = terrainGenerator;
....etc
}
public class TerrainGenerator
{
Simulator sim = new Simulator(this);
}
or
private final TerrainGenerator gen; //if you need to save this.
public Simulator()
{
this.gen = new TerrainGenerator(this);
....etc
}
private final Simulator sim; //If you need to save it.
public class TerrainGenerator
{
public TerrainGenerator(Simulator simulator) {
this.sim = simulator;
}
}

cannot find symbol symbol: method location: class

Sorry, just learning Java; but, can someone tell me why I'm getting a "cannot find symbol" error?
My code is as follows:
public class NumberHolder {
public int anInt;
public float aFloat;
public NumberHolder(int setAnInt, float setAFloat) {
setAnInt = anInt;
setAFloat = aFloat;
}
public static void main(String[] args) {
NumberHolder newNumber = NumberHolder(12, 24F);
}
}
Looks like you're missing a new before the call to the constructor:
NumberHolder newNumber = new NumberHolder(12, 24F);
EDIT:
Also, as Tassos Bassoukos points out in his answer, you need to turn around the assignments in the constructor:
anInt = setAnInt;
aFloat = setAFloat;
Although personally, I like to write my constructors like this:
public NumberHolder(int anInt, float aFloat) {
this.anInt = anInt;
this.aFloat = aFloat;
}
This is a matter of style and personal preference, though.
Since
public NumberHolder(int anInt, float aFloat);
is a constructor and not an ordenary method, you need to use the keyword new in order to obtain the actual object. You are calling it like a method and you don't have any method named NumberHolder (but it would be valid if you'd have)
Beyond the new keyword that you're missing, the assignment in the constructor should be the other way around.
You need to instanciate new objects with the new keyword.
public class NumberHolder {
public int anInt;
public float aFloat;
public NumberHolder(int anInt, float aFloat) {
this.anInt = anInt;
this.aFloat = aFloat;
}
public static void main(String[] args) {
NumberHolder newNumber = new NumberHolder(12, 24F);
}
}

Categories