I have an ArrayList which contains n instances of the class Boat. The class Boat has a number of methods which alter the instance variables of that boat.
For example:
public void Command(String command)
{
int inefficientwayofdoingthis=0;
if(command.equals("power on"))
{
inefficientwayofdoingthis++;
int x=1;
setpower(x);
System.out.println(name+" is on and is travelling in the direction of "+angle+" deg. with speed: "+ speed+"mph");
}
//...
The issue I am having is that this Command method should set the value of [instancename].power to 1.
The instances are contained in an ArrayList, data:
I am using the following code to alter the instances within the arraylist:
int numberinArray = whatever;
String theorder = "power on";
data.get(numberinArray).Command(theorder);
Each time I do so however, the command works and an output is produced, but subsequent commands do not seem to recognize that data.get(numberinArray).power should equal 1. I think I'm having a problem in that this is a deep copy of each instance of the class rather than a shallow copy. Would anyone have any suggestions on how to alleviate this issue?
if you want the power stay "attached" to the boat instance, this should be an instance variable. This could work in a way like this:
package com;
public class Boat {
private int power;
private String color;
Boat() {
// may want to initialize some values
this.setPower(0);
this.setColor("red");
}
public int getPower() {
return power;
}
public void setPower(int power) {
this.power = power;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
then you could add some other methods like applyCommand(String command) in your example
Related
I am trying to create a random car generator that also displays info. I thought I had everything until the randomCar portion. It says that
'com.company.Main.this' cannot be referenced from a static context
under the return statements in the switch. Any thought on to where I may be going wrong?
package com.company;
public class Main {
class Car{
private String name;
private boolean engine;
private int cylinders;
private int wheels;
public Car(String name){
this.name = name;
}
public String getName(){
return name;
}
public int getCylinders() {
if(cylinders == 0){
System.out.println("Unknown amount of cylinders");
}
return cylinders;
}
public int getWheels() {
return wheels;
}
public boolean isEngine() {
return engine;
}
}
class Tacoma extends Car{
public Tacoma(String name) {
super("Tacoma");
}
public boolean isEngine(boolean engine) {
return true;
}
public int getCylinders(int cylinders) {
return 6;
}
public int getWheels(int wheels) {
return 4;
}
}
class Motorcycle extends Car{
public Motorcycle(String name) {
super("Harley Davidson");
}
public boolean isEngine(boolean engine) {
return true;
}
public int getCylinders(int cylinders) {
return 2;
}
public int getWheels(int wheels) {
return 2;
}
}
class Volvo extends Car{
public Volvo(String name) {
super("Volvo");
}
public boolean isEngine(boolean engine) {
return true;
}
public int getCylinders(int cylinders) {
return 4;
}
public int getWheels(int wheels) {
return 4;
}
}
public static void main(String[] args) {
for (int i = 1; i<6; i++){
Car car = randomCar();
System.out.println("Car # " + i + ":" + car.getName() + "\n" +
"Number of cylinders: " + car.getCylinders() + "\n" +
"Number of wheels: " + car.getWheels()+ "\n" +
"Engine is: " + car.isEngine());
}
}
private static Car randomCar() {
int randomNumber = (int) (Math.random()*5) +1;
System.out.println("Random number generated is: " + randomNumber);
switch (randomNumber){
case 1:
return new Tacoma(); // This is where I am getting an error
case 2:
return new Motorcycle(); // This is where I am getting an error
case 3:
return new Volvo(); // This is where I am getting an error
}
return null;
}
}
I would start by reading here: https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html -> actually all the chapters there would be useful for you to read: https://docs.oracle.com/javase/tutorial/java/javaOO/index.html
Strictly speaking, to solve your "cannot be referenced from a static context" you can just make your classes static (Car, Tacoma, Motorcycle, Volvo) static class Car{
From my point of view you don't need nested classes, just create the classes in the same package as your Main class and you should be good to go (feel free to create more packages to better structure your classes)
Also I'm assuming your code is a work in progress because there are multiple issues with it:
methods like this don't make sense public boolean isEngine(boolean engine) {return true;} You receive a parameter that you ignore and you return a constant value: true; What I assume you want to do here is to have different types of cars each with its own predefined characteristics, but for that you should set the values for the attributes in the parent, Car. For this you either define protected setters, make the fields protected, or, best, create constructor which takes all the values
public Car(String name, boolean engine, int cylinders, int wheels) {
this.name = name;
this.engine = engine;
this.cylinders = cylinders;
this.wheels = wheels;
}
and you can have in Tacoma
public Tacoma(String name) {
super(name, true, 6, 4);
}
running your code I got the randomNumber 5 so that returned null and got a NPE, I assume work in progress
in your switch you are calling the default constructor new Tacoma() however that isn't available anymore since you defined a constructor with a parameter, use the available constructor or create the no-arg constructor.
There are other concerns regarding OOP principles so I recommend reading them again, just google "java OOP principles" and then "SOLID"... there are a lot of great resources out there, you just need time and patience and you'll get there!
When you put the Car class definition inside the class definition of Main, you made Car an inner class, so that a Car requires an outer class Main instance. In the static method there is no Main instance, and you can’t create the Car without it.
There is an immediate fix: add keyword static to the Car class:
static class Car {
which means there is no link to the enclosing object.
But there is no benefit here to making this a nested class, it would be better not to put one class definition inside another when you’re starting out.
The inner classes you've defined are instance members, meaning they belong to a specific instance of Main, and thus cannot be referenced from a static context that doesn't have a Main instance. The easiest way to resolve this would be to declare all the inner classes static.
First of all, to solve your error: 'com.company.Main.this' cannot be referenced from a static context, make all the methods static:
static class Car{//code here}
static class Volvo extends Car{//code here}
static class Tacoma extends Car{//code here}
static class Motorcycle extends Car{//code here}
Whenever you see that error, it means one static method is calling a non-static method. Therefore, just make both non-static or both static. The only exception is public static void main(String[] args); which must be static.
After solving the original errors, there is more to debug:
'Volvo(java.lang.String)' in 'com.company.Main.Volvo' cannot be applied to '()'
'Motorcycle(java.lang.String)' in 'com.company.Main.Motorcycle' cannot be applied to '()'
'Tacoma(java.lang.String)' in 'com.company.Main.Tacoma' cannot be applied to '()'
All this means is that your methods Tacoma(), Volvo(), and Motorcycle() require the parameter String name. So all you have to do is give them a name: here, it's
`new Tacoma("cool")`
new Volvo("car")
new Motorcycle("harley davidson")`
Finally, after solving the static and parameter problems, you are getting a NullPointerException, because randomCar() returns null. Your method says Car randomCar(), indicating it will return a Car, but then the return statement was return null;. Therefore, just return a Car - rtn here for our purposes:
private static Car randomCar() {
int randomNumber = (int) (Math.random()*5) +1;
System.out.println("Random number generated is: " + randomNumber);
Car rtn = null;
switch (randomNumber){
case 1:
rtn = new Tacoma("cool"); // This is where I am getting an error
case 2:
rtn = new Motorcycle("harley davidson"); // This is where I am getting an error
case 3:
rtn = new Volvo("car"); // This is where I am getting an error
}
return rtn;
}
This isn't all the debugging your code needs, but it's a start: here's what the system did so far:
Random number generated is: 3
Unknown amount of cylinders
Car # 1:Volvo
Number of cylinders: 0
Number of wheels: 0
Engine is: false
Random number generated is: 5
Hooray!
Did this help?
Say I have a class Person, and I created 10 instances of Person, and each person has several different attributes, such as enum Gender{MALE, FEMALE}, enum Profession{CEO, POLICE, TEACHER}, etc.
And I somehow have to randomly create many persons with random attributes and use a dedicated class to audit the statistics of created persons' attributes.
So, eventually, I need to generate a list of attributes with some statistics accordingly, such as, "FEMALE: [number], POLICE: [number],...".
Currently, I'm planning to add all kinds of the persons' attributes count, as a bunch of new attributes to the audit class, such as, "femaleCount int, policeCount int, ..." then manipulate the counts based on generated persons.
But, I got 10-ish attributes for each person, so I wonder if there is a better way to do this.
Thanks for your reading.
One possible approach is below, but do not say that it's the only one neither the best.
It's only depends of the purpose and your design.Other option maybe it's to store all Persons in a data-structure List and just compute the statistic based on data at a certain time (have also update/delete here)
Version where only add is counting ...
public class Statistic
{
private static Statistic s=null;
public int countPerson;
public int countMale;
public int countFemale;
public static Statistic getInstance()
{
if(s==null)
s = new Statistic(0, 0, 0);
return s;
}
public static Statistic getInstace(int cP,int cM, int cF)
{
if(s==null)
s = new Statistic(cP, cM, cF);
return s;
}
//do whatever init wanted
private Statistic(int cP,int cM, int cF)
{
countPerson = cP;
countMale = cM;
countFemale = cF;
}
public String toString()
{
return "Total="+countPerson+", Male="+countMale+", Female=" + countFemale;
}
}
...
public class Person
{
public int id;
public String name;
public Gender g;
public Profession p;
public enum Gender{MALE, FEMALE};
public enum Profession{CEO, POLICE, TEACHER}
Person(int id,String name, Gender g, Profession p)
{
this.id = id;
this.name = name;
this.g = g;
this.p = p;
Statistic.getInstance().countPerson++;
if(g.equals(Gender.MALE))
{
Statistic.getInstance().countMale++;
}
else
{
Statistic.getInstance().countFemale++;
}
}
}
...
public class TestStat {
public static void main(String[] args)
{
//cPersons,cMale,cFemale - init
Statistic.getInstace(10, 5, 5);
System.out.println(Statistic.getInstance());
new Person(1,"Male",Person.Gender.MALE, Person.Profession.TEACHER);
System.out.println(Statistic.getInstance());
new Person(2,"Female",Person.Gender.FEMALE, Person.Profession.CEO);
System.out.println(Statistic.getInstance());
}
}
Output
//custom start from (10,5,5) based on Singleton Custom Constructor
Total=10, Male=5, Female=5
//start update counters
Total=11, Male=6, Female=5
Total=12, Male=6, Female=6
Thinking twice maybe it's better to keep a List with Persons on Singleton
and make each time a new Computation - from Singleton instead on Person.
About Delete a person which can be translated in "moving from a Company to other" and then it's not to be reflected on Statistic.
Even so, on current you could add a delete method on person which could be reflected with adjust Statistic with minus and Person-Instance with null.
Further, it's up to you to update design as wanted.
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.
I'm trying to track class stats for an android game I'm working on.
public static class characterClasses {
public String class_name;
public int base_hp;
public int base_attack;
public float base_defense;
}
I want to access these directly by name so I won't have to iterate over them repeatedly. From my research it looks like a hashmap or map would be what I need but everything I've seen is only for a single key/value pair. I need to access each stat value directly by class and value, something like
classList.get("warrior").get("base_hp");
Can someone point me in the right direction?
You are correct to think of using HashMap. You can use the characterClass String names as keys and the characterClasses as values. You can then use your getter methods to access your specific fields i.e.
classList.get("warrior").getBase_HP();
You could also forget maps entirely since these stats seem constant by using inheritance
public class Character {
int hp;
int attack;
int defense;
public Character (int hp, int attack, int defense) {
this.hp = hp;
this.attack = attack;
this.defense = defense;
}
public int getHP() {
return hp;
}
...
}
For your Character subclasses, you can preset those values in the constructor
public class Warrior extends Character {
public Warrior() {
super(2, 10, 8);
}
public int getHP() {
return super.getHP();
}
}
public class Wizard extends Character {
public Wizard() {
super(10, 3, 1);
}
public int getHP() {
return super.getHP();
}
}
This way all your Warrior and Wizard Objects will have the same stats that can be accessed any time simply by invoking their getters.
First I'm new and don't know if this is against the rules but I'm looking for a little help on my homework. I don't want a full answer, just a step in the right direction. The problem is as follows:
Mick’s Wicks makes candles in various sizes. Create a class for the business named Candle that contains data fields for color, height, and price. Create get methods for all three fields. Create set methods for color and height, but not for price. Instead, when height is set, determine the price as $2 per inch. Create a child class named ScentedCandle that contains an additional data field named scent and methods to get and set it. In the child class, override the parent’s setHeight() method to set the price of a ScentedCandle object at $3 per inch. Write an application that instantiates an object of each type and displays the details. Save the files as Candle.java, ScentedCandle.java, and DemoCandles.java.
Now I believe I have done the classes correctly but the issue I'm having is the "Write an application that instantiates an object of each type and displays the details." I just dont get it. Here's my code:
public class Candle {
public static int color; //Declaring Variables
public static int height;
public static int price;
Candle(int startColor, int startHeight, int startPrice) { //Constructor
color = startColor;
height = startHeight;
price = startPrice;
}
public static int getColor() //Public methods
{
return color;
}
public void setColor(int color)
{
Candle.color = color;
}
public static int getHeight()
{
return height;
}
public void setHeight(int height)
{
Candle.height = height;
}
public static int getPrice()
{
return price;
}
public void setPrice(int price)
{
Candle.price = 2 * height;
}
}
public class ScentedCandle extends Candle { //Creating subclass to superclass Candle
public static int scent; //Delcare Variable
public ScentedCandle(int startScent,int startColor, int startHeight,int startPrice) { //Constructor
super(startColor, startHeight, startPrice); //Calling from superclass Candle
scent = startScent;
}
public static int getScent() //Public methods
{
return scent;
}
public void setScent(int scent)
{
ScentedCandle.scent = scent;
}
public static int getPrice()
{
return price;
}
#Override
public void setPrice(int price)
{
Candle.price = 3 * height;
}
}
public class DemoCandles { //Here is where I'm lost and have no clue
public static void main(String[] args) {
Candle getColor; //Declaring Variables
Candle getHeight;
Candle getPrice;
ScentedCandle getScent;
getColor = new Candle();
getHeight = new Candle();
getPrice = new Candle();
getScent = new ScentedCandle();
}
}
First of all you need to declare price as a product of height and 2.
"Write an application that instantiates an object
of each type and displays the details."
This basically mean Create a class with a main method in order to run your program.
In that main method, you need to instantiate your Candle class.
Instantiate means to create an object instance of your Candle class.
Something like this:
Object object = new Object(someInt, someInt, someInt); // or which ever constructor you decide to you
In order to get the properties of the object, use your get methods. If the property(data field) does not have a get method, get the property with something like this Object.property
And do like RC said, read up on static. You're not using it right