Cannot find symbol. Is looking in Superclass instead of subclass - java

I have a program that interprets and sorts data for a car dealer, and there is an error when trying to retrieve the color of the cars stored in an array.
Here is the main class and its sub class.
class Car
{
protected String model;
protected int price;
protected int year;
public Car(String m, int y, int p)
{
model = m;
price = p;
year = y;
}
}
class NewCar extends Car
{
protected String color;
public NewCar(String m, int y, int p, String c)
{
super(m, y, p);
color = c;
}
public String toString()
{
return "Model: " + model + "\n"
+ "Year: " + year + "\n"
+ "Price: $" + price + "\n"
+ "Color: " + color + "\n"
+ "Selling Price: " + price + "\n\n";
}
}
Here is another class in which the error occurs, at if(cars[z].color.equals(shade)).
The program cannot find variable color in class Car.
class CarDealerShip
{
public String printAllCarsOfColor(String shade)
{
String s = "";
for(int z = 0; z < i; z++)
{
if(cars[z].color.equals(shade))
{
s += "Car " + (z + 1) + "\n" + cars[z].toString();
}
}
return s;
}
How can I have the program look in class NewCar where variable color exists?

Your array cars appears to be of type Car[]. With a reference variable of Car after you have referenced the array element, there is no way to tell if it refers to a Car, a NewCar, or another subclass of Car.
It looks like you expect cars[z] to have the attribute color, so perhaps cars should be of type NewCar[] instead of Car[].
Another option is to move the attribute color to the superclass Car so any Car can have a color.

When using protected access the field will be available in classes that are within the same package or are a subclass of the base class. I'm assuming the class CarDealerShip which accesses the color field is not within the same package or does not extend Car.

The color is protected in NewCar. You can access protected variable only in sub classes. You need to move color to Car and add a public String getColor() method in your Car to make it available for the classes which are not part of the Car inheritance hierarchy.
public String getColor() {
return color;
}
and then your condition would be
if(cars[z].getColor().equals(shade))
Update
In case you want color to be in NewCar, you should add the public String getColor(); method in NewCar and your cars[] should be NewCar[], something like,
NewCar cars[] = new NewCar[arraySize]();
with this you will loose the inheritance capabilities, you can not use Car cars[] = new NewCar[arraySize] anymore.

If it's a requirement that color has to be in class NewCar you could use the instanceof operator and then cast it:
class CarDealerShip
{
public String printAllCarsOfColor(String shade)
{
String s = "";
for(int z = 0; z < i; z++)
{
if (cars[z] instanceof NewCar)
{
NewCar nc = (NewCar)cars[z];
if (nc.color.equals(shade))
{
s += "Car " + (z + 1) + "\n" + nc.toString();
}
}
}
return s;
}
}
You actually skip every Car that it not a NewCar and use only those that are an instance of the class NewCar.

Related

Own Object can't be added to ArrayList. instead all objects are overwritten

I try to determine the error since yesterday, but did not find him. All I know is where he must be placed approximately. But now to the topic.
For my app I have created a separate class with the name Player. Now if I make an ArrayList with this class, a newly added object overwrites all existing objects. So:
ArrayList empty -> Player is stored in ArrayList
ArrayList already contains a Player -> ArrayList now contains the newest Player instance two times
etc.
Here is my code corresponding to:
Player Object
public Player(String n, int m, int t) {
name = n;
money = m;
tip = t;
}
public String getName() {
return this.name;
}
public int getMoney() {
return this.money;
}
public int getTip() {
return this.tip;
}
public String toString() {
return this.name + "\n Tipp: " + this.tip + " | Einsatz: " + this.getMoney() + " ,- €";
}
Creating the ArrayList
public void addPlayertoEvent(String name, int money, int tip) {
Player p = new Player(name, money, tip);
playerList.add(p);
playerListString.add(p.toString());
lvPlayers.setAdapter(null);
ArrayAdapter<String> playerAdapter = new ArrayAdapter<String>(AddEventActivity.this, R.layout.list_items, playerListString);
lvPlayers.setVisibility(View.VISIBLE);
lvPlayers.setAdapter(playerAdapter);
etTip.setText("");
etName.setText("");
for(int i = 0; i < playerList.size(); ++i) {
Log.e("AL", "" + playerList.get(i).getName() + " " + playerList.get(i).getMoney() + " " + playerList.get(i).getTip());
}
}

Development of monopoly game

I seem to have a problem with a subtask. It's in danish so I put in the translated version of it:
Create a class Field, that is representing the fields of a monopoly game. Initially, Field can contain these encapsulated variables:
String name - short name of the field
int number - a number in the range[1..40]
Both variables must be initialized in a constructor, and there must only be getters, as they never will be changed after creation.
Moreover, there should be a method with the signature public String toString(), so it's easy to print what Field a player has landed on.
At first it's allowed to just call the fields Field1, Field2...
My Field class look like this:
public class Field {
String name;
int number;
public Field(String name, int number) {
this.name = name;
this.number = number;
}
public String getName() {
return name;
}
public int getNumber() {
return number;
}
}
In my main method I wanted to test this. So I wrote the following:
Field[] board = new Field[40]; // a board containing 40 fields
for (int i = 0; i < board.length; i++) {
board[i] = new Field("Field" + (i + 1), i + 1);
}
System.out.println("Board: " + Arrays.toString(board));
In my console I get this:
Board: [test.Field#2a139a55, test.Field#15db9742, test.Field#6d06d69c,......]
And I want this:
Board: [Field1, Field2, Field3,......]
Override Field's toString() to return the name, i.e.
public String toString() {
return name;
}
What you get (e.g. test.Field#2a139a55) is the default implementation of toString() which can be found in Object:
public String toString() {
return getClass().getName() + "#" + Integer.toHexString(hashCode());
}
You missed the
Moreover, there should be a method with the signatur public String toString(),
part of your task.
Are you able to use java8? Then I would suggest this:
Field[] board = new Field[40]; // a board containing 40 fields
for(int i = 0; i < board.length; i++){
board[i] = new Field("Field" + (i + 1), i + 1);
}
String commaSeparatedName =
Arrays.stream(board) // all items as stream
.map(Field::getName) // for each take its name
.collect(Collectors.joining(", "); // join names with a comma
System.out.println("Board: [" + commaSeparatedNames +"]");

How to display an istanceof an object in an arraylist? (Polymorphism)

I am trying to display all of the elements in the ArrayList plantList.
My main program will add, delete, search, filter, and display all of the plants of four different child classes. Everything "seems" to be working except when I display.
~I will only including portions of my code that are relevant to the questions.
A little background: I am a student and this is my first time working with inheritance/polymorphism.
1)How do I distinguish between the different objects since they all have different parameters, at the time of displaying?
2) Any suggestions on how to improve the performance/logic of what I'm doing? A little explanation would be great.
//Parent class
public class Plant{
private String name;
private String id;
private String color;
public Plant(String name, String id, String color){
this.name = name;
this.id = id;
this.color = color;
}
public String getName(){
return this.name;
}
public void setName(String name){
name = this.name;
}
public String getId(){
return this.id;
}
public void setId(String id){
id = this.id;
}
public String getColor(){
return this.color;
}
public void setColor(String color){
color = this.color;
}
}
//one of several child classes
public class Flower extends Plant{
private boolean thorns;
private boolean smell;
public Flower(String name, String id, String color, boolean blnThorns, boolean blnSmell){
super(name, id, color);
thorns = blnThorns;
smell = blnSmell;
}
public boolean isThorns(){
return thorns;
}
public void setThorns(boolean blnThorns){
thorns = blnThorns;
}
public boolean isSmell(){
return smell;
}
public void setSmell(boolean blnSmell){
smell = blnSmell;
}
}
// portion of the main driver
ArrayList<Plant> plantList = new ArrayList<Plant>();
//adding a flower to the plantList
System.out.println("\nEnter the name of the flower to add: ");
name = add.nextLine();
System.out.println("\nEnter the ID code: ");
id = add.nextLine();
System.out.println("\nEnter the color: ");
color = add.nextLine();
System.out.println("\nAre there thorns present? (True/False) ");
blnThorns = add.nextBoolean();
System.out.println("\nDoes the flower smell? (True/False) ");
blnSmell = add.nextBoolean();
plantList.add(new Flower(name, id, color, blnThorns, blnSmell));
System.out.println("Flower inserted.");
System.out.println();
break;
//displaying all plants
for( int i = 0; i < plantList.size(); i++){
System. out.println("\t" + (i+1) + ":");
System.out.print("\n\tName: " + plantList.get(i).getName());
System.out.print("\n\tName: " + plantList.get(i).getId());
System.out.print("\n\tColor: " + plantList.get(i).getColor());
if(plantList instanceof Flower){ // HERE I am not sure what I'm doing or how to do it
System.out.print("\n\tThorns presence: " + plantList.get(i).isThorns()); /* this is an example of what is not working properly */
System.out.print("\n\tSmell presence: " + plantList.get(i).isSmell()); /* this is an example of what is not working properly*/
System.out.println("\n");
}
}
If by "display" you mean "print some sort of string to the console or other output", then the answer is fairly simple: there's no need to use instanceof at all. All you need to do is override the toString method in each different class that you want to be displayable, then when you want to display an object (even if you don't know exactly what type it is), just call toString on it and print the result. Polymorphism will do the job of picking which toString method implementation to call.
Here's how it would look in your specific example.
In the Plant class:
#Override
public String toString() {
return "\n\tName: " + getName()
+ "\n\tName: " + getId()
+ "\n\tColor: " + getColor();
}
Then, in the Flower class:
#Override
public String toString() {
return super.toString()
+ "\n\tThorns presence: " + isThorns()
+ "\n\tSmell presence: " + isSmell();
}
Finally, to display all plants:
for (Plant plant : plantList) {
System.out.println(plant);
}
Note that toString is called automatically when you pass any Object to System.out.println.
You were really close. You just needed to check against the element of the list, not the list itself, when you did the instanceof check. Then, if it is in fact an instance of Flower, then you need to cast the list element to a Flower and make the method calls from there.
Like this:
for(int i = 0; i < plantList.size(); i++){
System.out.println("\t" + (i+1) + ":");
System.out.print("\n\tName: " + plantList.get(i).getName());
System.out.print("\n\tName: " + plantList.get(i).getId());
System.out.print("\n\tColor: " + plantList.get(i).getColor());
if (plantList.get(i) instanceof Flower) {
Flower flower = (Flower)plantList.get(i);
System.out.print("\n\tThorns presence: " + flower.isThorns());
System.out.print("\n\tSmell presence: " + flower.isSmell());
System.out.println("\n");
}
}

toString return different values

I'm pretty new in java and I'm doing a simple program but I don't know why I get different values, i.e., if I use getX, getY and getZ I get (6,5,8) but if I use toString I get different values for X and Y (3, 4, 8), so can anyone explain me why it happens because as far as I understand it should get the same values in both cases or what I'm doing wrong?
public class Coordinates {
private double coorX, coorY;
Coordinates()
{
coorX = 1;
coorY = 1;
}
Coordinates(double x, double y)
{
coorX = x;
coorY = y;
}
void setX(double x)
{
coorX = x;
}
void setY(double y)
{
coorY = y;
}
double getX()
{
return coorX;
}
double getY()
{
return coorY;
}
public String toString()
{
String myString = "(" + coorX + " , " + coorY + ")";
return myString;
}
public class Coordinates3D extends Coordinates{
private double coorZ;
Coordinates3D()
{
super();
coorZ = 1;
}
Coordinates3D(double x, double y, double z)
{
super(x,y);
coorZ = z;
}
public void setZ(double z)
{
coorZ = z;
}
double getZ()
{
return coorZ;
}
#Override
public String toString()
{
String myString = "(" + coorX + " , " + coorY + " , " + coorZ + ")" ;
return myString;
}
}
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Coordinates test1 = new Coordinates(3,4);
System.out.println(test1.toString());
System.out.println(test1.getX());
System.out.println(test1.getY());
Coordinates3D test2 = test1.new Coordinates3D(6,5,8);
System.out.println(test2.toString()); ---> here is the problem
System.out.println(test2.getX());
System.out.println(test2.getY());
System.out.println(test2.getZ());
}
}
First there is a problem on how you define the visibility of the fields of the super class:
public class Coordinates {
//defines as private
//sub classes cannot access to these fields directly
private double coorX, coorY;
This is that you cannot invoke super.coorX nor super.coorY on any sub class e.g. Coordinates3D. So, in toString method, when you have this code:
String myString = "(" + coorX + " , " + coorY + " , " + coorZ + ")" ;
It compiles and runs fine because Coordinates3D is an inner class. So, when using coorX here it's accessing to the value of coorX field stored in the instance of Coordinates class that created the instance of Coordinates3D. This can be easy to replicate if you separate the classes:
class Coordinates {
private double coorX, coorY;
}
public class Coordinates3D extends Coordinates {
//current code...
#Override
public String toString() {
//now you will get a compilaton error
String myString = "(" + coorX + " , " + coorY + " , " + coorZ + ")" ;
return myString;
}
}
The best solution would be:
mark the fields in the super class as protected
separate the classes
If you still want to keep Coordinates3D as inner class (not recommended), then:
mark the fields in the super class as protected
use super.coorX and super.coorY to not have the same unexpected behavior.
I would like to add to the existing answers that even in the class, you should not read the fields firectly, but use their getters.
#Override
public String toString() {
String myString = "(" + getX() + " , " + getY() + " , " + getZ() + ")";
return myString;
}
This also fixes the problem, but you should still not make the Coordinates3D class an inner class of Coordinates.

Java: method not working

I am creating a program that simulates some people catching fish in a lake, I already created classes for Fish and Pond and I was working on the Fisher class and a method is not working and I'll show the code (I'm new to programming so I'm not sure if I am providing enough information)
public class Fisher {
public static int LIMIT = 3;
private String name;
private Fish[] fishCaught = new Fish[LIMIT];
private int numFishCaught;
private int keepSize;
public Fisher(String name, Fish[] fishCaught, int numFishCaught, int keepSize) {
this.name = name;
this.fishCaught = fishCaught;
this.numFishCaught = numFishCaught;
this.keepSize = keepSize;
}
public String getName() {
return name;
}
public Fish[] getFishCaught(){
return fishCaught;
}
public int getNumFishCaught() {
return numFishCaught;
}
public int getKeepSize() {
return keepSize;
}
public String toString() {
return (name + " with " + numFishCaught + " fish");
}
public void keep(Fish f) {
if (numFishCaught == LIMIT) {
} else {
numFishCaught++;
fishCaught[numFishCaught-1] = f;
}
}
boolean likes(Fish f) {
if ((f.getSize() >= keepSize) && !(f.getSpecies().equalsIgnoreCase("Sunfish"))) {
return true;
}
return false;
}
public void listFish(){
System.out.println(name + " with " + numFishCaught + " as follows: ");
for (int i = 0; i<numFishCaught; i++){
Fish f = new fish[i];
System.out.println("A " + f.getSize() + " cm " + f.getFishCaught());
}
}
}
the problem is the listFish() method, it's supposed to return something like this:
Bob with 2 fish as follows:
A 4 cm Pike
A 15 cm Bass
but it's not working it gives me "incompatible types" and "cannot find symbol" errors??
(just to make your life easier i'll include the Fish class too)
public class Fish {
private String species;
private int size;
public Fish(int size, String species) {
this.size = size;
this.species = species;
}
public String toString() {
return " A " + size + " cm " + species;
}
public String getSpecies() {
return species;
}
public int getSize() {
return size;
}
}
Error: /Users/halahalhomoud/Fisher.java:57: incompatible types
found : Fish[]
required: Fish
File: /Users/halahalhomoud/Fisher.java [line: 58]
Error: /Users/halahalhomoud/Fisher.java:58: cannot find symbol
EDIT:
show you how? I used it in the Pond class and it worked fine but I don't get why it's not working here.
You want the fish that are caught by a Fisher. Now, you have that information in the array you can retrieve with getFishCaught.
Now look what you try to do instead:
Fish f = new fish[i];
System.out.println("A " + f.getSize() + " cm " + f.getFishCaught());
In the first line, you try to make a new array of fish, but it is, of course Fish (fish is the symbol that couldn't get resolved.). Then you try to assign the array reference to a single Fish f. But an array of Fish is not the same as a Fish. For example, you can eat a Fish, but not a Fish container, you know.
What you probably want is this:
Fish f = (getFishCaught())[i]; // get the i-th Fish caught
System.out.println("A " + f.getSize() + " cm " + f.getXXX());
where getXXX is a method of Fish that returns the Fishs species. (Since you didn't show the FIsh class, I can't know the exact name of this getter).
Fish f = new fish[i];
should be:
Fish f = fishCaught[i];
Complete Method
public void listFish(){
System.out.println(name + " with " + numFishCaught + " as follows: ");
for (int i = 0; i<numFishCaught; i++){
if(fishCaught[i] != null){
Fish f = fishCaught[i];
System.out.println("A " + f.getSize() + " cm " + f.getSpecies());
}
}
}

Categories

Resources