I am running following code in java and have some questions.
I am calling following line in a Test class:
building.floor(3).waitForElevator();
My Building class has following method which returns the floor object from an array (floors) for given floorNumber.
ArrayList<Floor> floors = new ArrayList<Floor>();
public Floor floor(int floorNumber) {
return floors.get(floorNumber);
}
My Floor class has waitForElevator() method. In my Floor class I also have an array of length 7 called passengerWaiting. Whenever waitForElevator() is called, I would like to access the correct floorNumber in passengerWaiting array and change its value.
What I am struggling with is when building.floor(3).waitForElevator() is called, how do I access the index (3 in this example) from Floor class.
Thanks for all the help in advance.
You could store the value in a class instance variable and make it accessible via an accessor.
public class Building{
private int floor = 0;
private ArrayList<Floor> floors = new ArrayList<Floor>();
public Buliding(){
Floor floor1 = new Floor(this);
this.floors.add(floor1);
}
public Floor floor(int floorNumber) {
this.floor = floorNumber;
return floors.get(floorNumber);
}
public int getFloor(){
return floor;
}
}
If you add a constructor for Floor that accepts an instance of building and stores it as an instance variable you can access floor at any time.
public class Floor{
private Building building;
public Floor(Building building){
this.building = building;
}
public void waitForElevator(){
int floor = this.building.getFloor();
}
}
Another Solution
Simply pass the int to waitForElevator as an argument.
public class Floor{
public void waitForElevator(int floor){
System.out.println(floor);
}
}
//Usage
building.floor(3).waitForElevator(3);
Note This solution is not as great because the client could invoke as building.floor(3).waitForElevator(4);
To solve your current problem, I would suggest having each floor keep an int of which floor it is.
However, that seems like code smell to me, so I must ask why you need to do it this way. Could you possibly implement it such that you could just call building.waitForElevator(3)? Another refactoring would be to, rather than have one passengerWaiting ArrayList, have an int value for passengerWaiting in the Floor class, and just change that on each call to waitForElevator.
If you would post your full problem, I could give more helpful of suggestions, I'm guessing here based on the snippets you posted.
Related
The purpose of this program is to create a class and tester class for a select object(in my case a monitor), with at least one overloaded method. And in the client class, I have to instantiate at least three instances of the object. So far I believe I've finished the first class with the declaration of methods, getters and setters, and constructors. The problem occurs in my tester class, where I get the error "Cannot resolve method 'MonitorV82' in 'Monitor V82'. I don't know for sure why I'm getting this error, any advice?
My first class is:
public class MonitorV82
{
private double l;
private double h;
//one parameter constructor, all private instance variables initialized
public MonitorV82(double monitor1Height) {
//2.When this gets name1(jupiter), it designates "jupiter" to the variable "n"
h = monitor1Height;
l = (monitor1Height * 1.77);
}
//two parameter constructor
public MonitorV82(double monitor1Height, double monitor1Length){
//3.When this gets name1(jupiter), and a double, it sets jupiter to "n" and the diameter to "d"
h = monitor1Height;
l = monitor1Length;
}
public double getMon1height() { return h; }
public double getMon1Length() {
return l;
}
public void setMon1height(double name) { h = name; }
public void setMon1Length(double diam) {
l = diam;
}
public String monType(int resolution)
{
String monitType = "";
if (resolution == 1080) {
monitType = "lenovo";
} else if (resolution == 4000) {
monitType = "samsung";
}
return monitType;
}
//overloaded method
public String monType(int pixLength,int pixHeight)
{
String monitType = "";
if (pixHeight == 1080) {
monitType = "lenovo";
} else if (pixHeight == 4000) {
monitType = "samsung";
}
return monitType;
}
}
My tester class(where the error is) is:
public class V8Tester {
public static void main(String[] args) {
double length1 = 32.2;
double height1 = 51.8;
double length2 = 31.8;
double height2 = 50.6;
int resolution = 0;
MonitorV82 monit1 = new MonitorV82(length1);
resolution = monit1.MonitorV82(height1);
}
}
I am still learning Java in school so please don't roast me if something seems obvious or simple. Thank you for your help.
You are getting this error because there is no method MonitorV82, only a constructor. Also you are trying to instantiate the int variable resolution with a MonitorV82 object, which is not possible, because the compiler expects an int value.
If you want the resolution that refers to the pixel count of the MonitorV82 object with known pixel height, you first need to find out it's pixel length. You can do this by using your getMon1length() method and the calculate the resolution by length * height. Ultimately what I think you are trying to do is:
int heightMonit1 = monit1.getMon1height();
int resolution = (int)length1 * (int)heightMonit1;
You need to type cast, because you want to instantiate the int variable resolution with a calculation of double values.
You could however also use your second constructor and do:
MonitorV82 monit1 = new MonitorV82(length1, height1);
int resolution = (int)monit1.getMon1height() * (int)monit1.getMon1length();
Before answering the question in the title, you need the answer to this question:
What is a constructor in Java?
A constructor in Java is a special method used to "construct" (build, instantiate, etc.) objects. A constructor follows these basic rules:
The name of the constructor should match exactly the class name. In your case, MonitorV82 is this name.
A constructor doesn't have a return type. The new operator is responsible for returning a new object matching the type of the class in which the constructor is being invoked.
Knowing this, let's address the original question: Why the error? Because in MonitorV82 there is only a constructor a with matching name, but not a regular method with the same name. Consider my example below
public class Test {
private String name = "default";
// constructor #1
public Test() {}
// constructor #2
public Test(String name) {
this.name = name;
}
// method #1
public void Test() {
System.out.println(name);
}
// method #2
public void Test(String name) {
System.out.println(name);
}
}
Notice that in the code above, I have two constructors and two methods with the same name (matching case) and same parameters. This is allowed in Java although this is STRONGLY discouraged due to how confusing it can get.
What does this mean for you?
To create monit1, you need to invoke a CONSTRUCTOR. Once you construct the object, you cannot use it to invoke a constructor. You use objects to invoke non-static, accessible methods. Based on this, the line
MonitorV82 monit1 = new MonitorV82(length1);
is totally fine. However, the set resolution line is not resolution = monit1.MonitorV82(height1); because you have no METHOD named MonitorV82 (you just have a constructor with a matching name). You fix this by creating a method in your class that does exactly that. Since method names should be descriptive of their function, creating a method named setResolution or calculateResolution should be fine. What you should not do is used an ambiguous name; especially using the same name as the constructor.
Lastly, I will leave you with this small piece of advice: Just because the language allows you to do something, that does not mean that it is correct or OK to do so. My code example (along with this lengthy explanation) should've illustrated this point.
tl;dr
You asked:
Why am I getting the error "cannot resolve method "x" in "x""?
Because your last line tries to call a method named MethodV82 which does not exist on an instance of the class named MethodV82.
Details
Firstly, you should have indicated which line of code is causing that error.
You have at least one offending line, that last line. The code monit1.MonitorV82(height1) makes no sense. That code is trying to call a method named MonitorV82 on the instance named monit1. But of course there is no such method. Thus the error « Cannot resolve method ».
I cannot follow your logic, so I cannot give a fixed replacement code snippet.
I think you are misunderstanding the use of constructors.
I guess that what you want to do with your monit1.MonitorV82(height1) is to set the height of your monit1 instance to height1.
You need to call the setter to do so, not a constructor. The constructor is not known as a class method, that is why your error occurs. Use
monit1.setMon1height(height1);
Next, I think that you are trying to retrieve a resolution from your monitor, but you have no method inside of your MonitorV82 with this aim so I suggest that you create a method for this such as
public int computeResolution() {
return this.h * this.l;
}
In your test class you end up with:
public class V8Tester {
public static void main(String[] args) {
double length1 = 32.2;
double height1 = 51.8;
double length2 = 31.8;
double height2 = 50.6;
int resolution = 0;
MonitorV82 monit1 = new MonitorV82(length1);
monit1.setMon1height(height1);
resolution = monit1.computeResolution();
}
}
Edit: Even the instantiation of your monit1 does not seem correct. The only one parameter constructor you have is based on height and you are calling it with length1
Edit2: My example of computeResolution() will probably end up with an exception as I am returning an int from a compute action on doubles. But I think that it is not the main issue here
General part first:
This is for my Java 1 final: I need to make an NFL playoff simulator. So, I would make a "Team" object that holds values for "Offense" and whatnot. I would need a method that holds an algorithm to calculate who wins each matchup. However, I don't know how to go about applying the method to the appropriate teams..
I was going to make another object called "Matchup" which would hold 2 "Team" objects, then comparing the 2 teams' values with the algorithm method. But, I don't think you can use objects inside another object, to my knowledge... Therefore, I've just been trying to hard-code everything in an ugly way.
Would anyone point me in the right direction of forming such a program?
Anyway, on to my immediate issue:
Here is my small bit of code thus far..
public class Final_Larrabee {
static Team pit = new Team("Steelers", "AFC", 3, 75, 70);
static Team bal = new Team("Ravens", "AFC", 6, 70, 80);
static String teamA1 = "bal";
public static void main(String[] args) {
System.out.println(+teamA1.seed);
}
}
And my other class:
package final_larrabee;
public class Team {
String name;
String conference;
int seed;
int offense;
int defense;
boolean wcWin;
boolean divWin;
boolean conWin;
boolean alive;
public Team(String n, String c, int s, int o, int d) {
name = n;
conference = c;
seed = s;
offense = o;
defense = d;
wcWin = false; // these wins will be used in the betting part
divWin = false;
conWin = false;
alive = true; // determines if team is out of playoffs or not
}
public String getName(){
return this.name;
}
public void setName(String n){
name = n;
}
public int getConference(){
return this.seed;
}
public void setConference(String c){
conference = c;
}
public int getSeed(){
return this.seed;
}
public void setSeed(int s){
seed = s;
}
public int getOffense(){
return this.offense;
}
public void setOffense(int o){
offense = o;
}
public int getDefense(){
return this.defense;
}
public void setDefense(int d){
defense = d;
}
}
I realize this won't work, because it is trying to access teanA1's seed value (which doesn't exist of course). But, what I wanted was to simply call the bal.seed value. I wanted to do it this way so that later, I can use teamA1 and teamA2 variables for the 2 teams in a given matchup. Is there a way to do it this way?
If not, perhaps ideally, it would be best to create a Team object called teamA1 which holds the values of whatever team I need at the time. It would need to change like a variable instead of make a million objects every time I need it (ideally..) I found the method 'clone' but I'm not sure this is what I want?
Any help, be it to my immediate question, or the general layout of my program, would be much appreciated. Thanks!
make team implements comparable this will give you the ability to write compareTo method and then you can put you win condition based
Just as your class Final_Larrabee holds 2 team objects in your code, your matchup class can also hold other objects.
Yes, you're on the right track with the idea of creating a matchup class which holds instances of team objects.
Inside your main class you can initialize 2 team objects. I would then create a matchup object, which gets passed the 2 team objects you have previously created and do some functionality.
Inside your team class you could implement a method, which returns a score based on the teams stats. For example it could calculate the offense * defence * seed or something like and return it that and then inside your match class, you can then implement a method such as playGame() which calls the getScore() method of each object and compares the values and then returns the winner (or prints them out for simplicity).
As regards your code, you're using the keyword static. Static is a keyword which changes a variable/object/method to a class variable/object/method. This means that every instance of the class shares this variable. I would not use it for creating the teams. An example of where to use static (a very basic example), would be if for some reason you needed to keep track of the amount of team objects you created. You could implement a static COUNT variable inside the team object and increase it by one every time the constructor is called. This could also be used for assigning IDs to the teams.
static int TEAM_COUNT = 0;
public Team()
{
this.id = ++TEAM_COUNT;
}
This would make the TEAM_COUNT be a value which shared by all instances of the class team. If you were to call
teamA.setTeamCount(0);
Then every other instance of Team would also be reset to 0.
Edit: With regards to your playoffs
public static void main(String args[])
{
Team team1 = new Team("parameters required here");
Team team2 = new Team("parameters required here");
Playoff p = new Playoff();
p.add(team1);
p.add(team2);
p.startPlayoffs();
}
If you create all of the objects inside the main class, then they are available to that method as they are local. When you call p.add(), you can add them to an array or collection, which is inside the Playoff class. Your startPlayoffs() method can then process the array of objects already stored inside the class.
For a turn-based game I want to make a build queue for a planet. User puts items to build in a queue and then, when turn is generated, everything in a queue is being built.
Right now I have a Planet class which has an ArrayList. An object of type Planet is created for each planet the player owns. The array list contains everything user has ordered this planet to build. It also contains 3 variables that store the resources currently present on the planet and 3 variables that store total number of buildings that are currently on the planet.
Every building type is also a class (because building types costs differ), I plan to put objects of corresponding type into the planets queue. I suppose that each building class should have its own building method .build();
I want to cycle through each item in the queue of the planet and launch something like .buld() method.
Building an object means subtracting some resources from the planets resource variables and adding number of buildings built to total number of buildings on a planet.
The trouble is that I don't understand the main idea, how to achieve this.
The Planet class:
public class Planet extends WorldObject implements Serializable {
private int defenses;
private int mines;
private int factories;
//it also has 3 variables from WorldObject class:
int iron;
int bor;
int ger;
ArrayList<Installation> queue;
private void build(){
for ( int i = 0; i < queue.size()-1; i++ )
{
queue.get(i).build();
}
}
}
One of the building classes:
public class Factory extends Installation {
int costIron = 10;
int costGer = 50;
public build(int amt) {
//build itself, remove res from planet, add number built to planet factory list
}
}
If I'm doing this totally wrong, I would be thankful if you say in which "direction" should I look for information.
It sounds like Planet should have a Resources object that encapsulates the resources, and that could be passed to Installation.build(). Then Installation.build() could return a object that describes what was built.
Edit: here's an example:
public class MineFactory extends Installation {
private final Resources cost;
public MineFactory(Resources cost) {
this.cost = cost.clone();
}
#Override
public Result build(Resources availableResources) {
if (!availableResources.remove(cost)) {
return Result.empty();
}
return Result.mines(2);
}
}
You need to either pass your Planet object to build as an argument so that it has access to resources, or, alternatively, do the "building" in the Panet code itself, and just have getCost on the building, that you'd call yo find out how much resources to subtract.
Personally, I'd know kinda prefer the latter approach, but that's more of a question if taste than anything else.
I am trying to pass a value from the main method and set it to a private variable. Here is the main method that's pertinent:
import java.util.*;
public class Experiment{
private static Extension extension=new Extension();
public static void main(String[] ars);{
Scanner input=new Scanner(System.in);
System.out.print("Enter the length: ");
int length=input.nextInt;
extension.messages(length); }
}
and here's what goes with it:
public class Extension{
private int theLength;
public void Extension(int length){
theLength=length; }
public void setLength(int length){
theLength=length; }
public int getLength() {
return theLength }
public void messages(int length){
System.out.println("theLength: "+theLength);
System.out.println("Length: "+getLength(); }
}
I added the extra display because I wanted to see if the value was getting passed on correctly. When I run it, I realize that it's not; both theLength and length are set to zero despite having input different numbers. Can anyone see what I'm doing wrong? I would sincerely appreciate a thorough answer (since I am just starting out).
You are not setting the private variable length. You should call the setLength(int length) method.
change to this
System.out.print("Enter the length: ");
int length=input.nextInt;
extension.setLength(length); // this will set the private variable
extension.messages(length);
This is a lesson in encapsulation. Your issue, as #salihrkc said, is that you're never actually setting the length variable which exists in your "Extension" object. If you try to print "length" as passed in to your object, you'll see it's getting there just fine.
You act on your object using the dot operator (e.g. extension.messages(length);, to call the messages method). The key points you should be realizing is that you cannot set the objects length by just doing extension.theLength = length;. This is because of the private modifier. Instead you should be using the "getter" and "setter" methods. These functions exist within your object and therefore access to the private variables, so you can do something like extension.setLength(length); and System.out.println(extension.getLength());
Check out the two sources I linked, they'll help.
Good luck.
Just doing a quick edit up at the top of my post.
The question is if i extend a class and both classes have the same variable why is the extended class getting the original classes value.
This has been answered but would be more than happy to read more information about this.
Polymorphism isn't a strong suit of my so i'm having to relearn this stuff after not using it for months.
So i'm trying to program a game and one of the requirements is some type of list of object that can be scanned in a loop. The trouble starts with my test of ArrayList. I have 3 classes i made to be added in to my array list. Entities, Monster extends Entities, and Character extends Entities. do note Monster and Character both extends Entities class.
I decided that i should make the ArrayList and added new objects directly in to each element(the word element is normally used with array not ArrayList correct?) and use a log function i programmed to note down values of the objects in the ArrayList.
I made a for loop and ran both Monster and Character .getHP() method that they inherited from Entities and the results was the HP from Entities not Monster or Character unless i added a new value to the classes HP using the setHP(int i) method also inherited Entities.
Since my program requires most of the classes and we only need about 99% i decided to make a test project to basically do the above in a smaller form since i don't want to be copying pasting 20 or more .java files here. Anyways here's my test classes and results.
import java.util.ArrayList;
// class to test interactions between Extended classes
public class testHP {
ArrayList<Entities> ent = new ArrayList<Entities>();
public static void main(String[] args) {
///make reference varaible so i don't have to make test() and ent static.
testHP hp = new testHP();
hp.test();
}
void test(){
/// the 3 classes to the arraylist. I could of made a reference variable but didn't.
this.ent.add(new Character());
this.ent.add(new Monster());
this.ent.add(new NPC());
///prints out whats in the array list so i know that i have the correct objects.
System.out.println(this.ent);
/// this prints out { ent(i) HP "is" i } to tell which class is being called and it's HP at this point.
for(int i=0; i<ent.size();i=i+1) {System.out.println(this.ent.get(i).getHP() +" is "+ this.ent.get(i));}
/// this adds i plus 10 then does the same as the last for loop.
for(int i=0; i<ent.size();i=i+1) {
this.ent.get(i).gainHP(i+10);
System.out.println(this.ent.get(i).getHP() +" is "+ this.ent.get(i));}
}
}
abstract public class Entities {
private int HP = 1;
int getHP(){
return HP;
}
void gainHP(int hp){
HP = this.HP + hp;
}
}
///Character is to show what happens when i change the value and make it static.
public class Character extends Entities {
private static int HP = 4;
}
///monster is to show a changed variable from the super which is entities.
public class Monster extends Entities {
private int HP = 4;
}
/// NPC is a class that just to have variables from entities class that aren't edited or made static.
public class NPC extends Entities {
}
here is my results with these files as they are above. I should have put HP next to the number to the left but you get the idea.
[Character#67f1fba0, Monster#3fbefab0, NPC#133c5982]
1 is Character#67f1fba0
1 is Monster#3fbefab0
1 is NPC#133c5982
11 is Character#67f1fba0
12 is Monster#3fbefab0
13 is NPC#133c5982
My test class for the original ArrayList looks like this.
import java.util.ArrayList;
public class AreaMap extends Map {
String CLASS = "Area Map";///log requires.
ArrayList<Entities> ent = new ArrayList<Entities>();
AreaMap(){
Log.Logging(CLASS,"Testing arrayList");
//random text added to the array.
ent.add(new Character());
ent.add(new Monster());
Log.Logging(CLASS, "ent 1 has " +ent+ " in it");
for(int i=0; i < ent.size();i = i+1){
Log.Logging(CLASS, "ArrayList " + this.ent.get(i).getHealth() +" i="+i);
}
for(int i=0; i < ent.size();i = i+1){
this.ent.get(i).setHP(10+i);
Log.Logging(CLASS, "ArrayList " + this.ent.get(i).getHealth() +" i="+i);
}
}
}
And here are my result from that.
[Area Map]##[Testing arrayList]
[Area Map]##[ent 1 has [Character#2bd1e730, Monster#61a116c9] in it]
[Area Map]##[ArrayList 0 i=0]
[Area Map]##[ArrayList 0 i=1]
[Area Map]##[ArrayList 10 i=0]
[Area Map]##[ArrayList 11 i=1]
Do note that "Log" is a class i made and the method is "static Logging(String origin, String Action){System.out.println([origin]+"##"+[Action]);"
origin is always the class not that it has to be.
Sorry if this isn't clear. If you need more information to help me i'm more than willing to answer.
Basically the problem is that you're trying to declare extra variables in subclasses as if they can "override" the variable in the superclass. Variables don't work that way - they're not polymorphic.
If you need to give each class a different starting number of hit points, I suggest you create a protected constructor in Entities (which should be renamed, btw - e.g. AbstractEntity) to take the initial value of HP (which should probably be renamed hitPoints). Then each subclass would have a public constructor to call the superconstructor with an appropriate value.
For example:
public abstract class AbstractEntity {
private int hitPoints;
protected AbstractEntity(int initialHitPoints) {
this.hitPoints = initialHitPoints;
}
public int getHitPoints(){
return hitPoints
}
void gainHitPoints(int amount) {
hitPoints += amount;
}
}
public class Monster extends AbstractEntity {
public Monster() {
// Every monster starts off with 4 hit points
super(4);
}
}
Now that's just a matter of changing the initial state. If you wish the different entities to behave differently, you should override the abstract class methods within the subclasses.
I believe your problem is scoping. The HP that Entities* is accessible from your getHP, but your HP in Character and Monster are different variables that happen to have the same name. Additionally, marking HP as private means that subclasses can't access that variable - I think you have protected.
What is probably the correct solution to get rid of HP in Monster and Character, make HP in Entities protected, and set the default HP in the default constructor for Monster and Character.
* It's good style to name your objects in the singular, so this is better named as Entity.
If I understand it correctly, the problem is as follows:
You declared the attribute HP as private in class Entities and declared a new(!) variable in the subclass (see the other answers).
You can resolve the behavior by setting HP by a constructors, e. g.,
class Entitites {
private int HP;
public Entities(int hp) {
this.HP = hp;
}
}
class Monster extends Entities {
public Monster() {
super(4);
}
}