1
else if (control.equals("Car") == true)
{
     owner = (scanner.nextLine());                     
     address = (scanner.nextLine());
     phone = (scanner.nextLine());
     email =(scanner.nextLine());
     convertible= (scanner.nextBoolean());
     color = (scanner.nextLine());

     vehicleLot[i] = new car(owner, address, phone, email, convertible, color);
     System.out.println(vehicleLot[i].getOwner());
     System.out.println(vehicleLot[i].getAddress());
     //System.out.println(vehicleLot[i].getColor());
}

The above code is in my main method. The line that is commented out throws out the error "cannot find symbol in the class vehicle". I am reading from a file and placing the information into the correct objects data fields. The array is an array of vehicles. From what I understand, an element of the array of vehicles can be a vehicle or any subclass of vehicle. Getters and setters methods are available for each respective class with subclass using the getters and setters for the parents class. Car is a subclass of vehicle. Why is it not trying to access cars methods first before trying vehicle when I just created the car object? Does the problem lie in my car constructor? car is static because it is a nested class and throws an error if you don't keep it static. Below is the summary of the car class.

static class Car extends vehicle
{
  private boolean convertible;
  private String color;
  public Car()
  {

  }
  public Car(String ownersName, String address, String phone, String email, boolean convertible, String color)
  {
      super.setOwner(ownersName) ;
      super.setAddress(address);
      super.setPhone(phone);
      super.setEmail(email);
      this.convertible = convertible;
      this.color = color;
      System.out.println(this.convertible);
  }//Car class ends

The System.out.println prints out the correct value for that string, so I'm interested as to why the object wants to try and only use the class vehicle for its methods instead of class car and class vehicle. Here is vehicle if that helps.

public static class Vehicle
{
    private String ownersName;
    private String address; 
    private String phone;
    private String email;

    public Vehicle()
    {
    }
    public Vehicle(String ownersName, String address, String phone, String email)
    {
        this.ownersName = ownersName;
        this.address = address;
        this.phone = phone;
        this.email = email;
     }
}//Vehicle class ends
2
  • Where do you set the value of control Commented Oct 23, 2014 at 16:55
  • You dont need the == true in control.equals("Car") == true since control.equals("Car") already returns a boolean Commented Oct 23, 2014 at 20:22

3 Answers 3

2

If I understood the question, you are asking why the following line doesn't compile :

System.out.println(vehicleLot[i].getColor());

vehicleLot is defined as an array of Vehicle. It can contain instances of any sub-classes of Vehicle. Therefore, vehicleLot[i] doesn't necessarily have a getColor() method, since that's a method of Car.

In order to access the methods of Car you have to cast the Vehicle reference to Car :

System.out.println(((Car)vehicleLot[i]).getColor());

This, of course, would only work if vehicleLot[i] refers to a Car instance. If not, a ClassCastException will be thrown.

Sign up to request clarification or add additional context in comments.

Comments

1

"Car is a subclass of vehicle. Why is it not trying to access cars methods first before trying vehicle when I just created the car object?"

This really only applies to polymorphic methods, those that are defined for a superclass, and then (possibly) overridden in a subclass. If you say

vehicle v;

the compiler knows only that v is a vehicle; therefore, it can only access methods defined for the vehicle class. If v is actually a car, and one of those methods is overridden for car, then it will call the method in car. But if you use a method that's defined only for car (not for vehicle), the compiler won't allow it, because it only knows that v is a vehicle, and it doesn't know that it will have a car method such as getColor. This is true even if you have just assigned v to a new car. The compiler looks only at the declaration vehicle v; it doesn't try to go backward through your program to figure out what you've assigned to it.

You can solve the problem with a cast, as in Eran's answer, but in this particular case you don't need to. Change

 vehicleLot[i] = new car(owner, address, phone, email, convertible, color);
 System.out.println(vehicleLot[i].getOwner());
 System.out.println(vehicleLot[i].getAddress());
 System.out.println(vehicleLot[i].getColor());

to

 car newCar = new car(owner, address, phone, email, convertible, color);
 vehicleLot[i] = newCar;
 System.out.println(newCar.getOwner());
 System.out.println(newCar.getAddress());
 System.out.println(newCar.getColor());

The compiler may think vehicleLot[i] can be any vehicle, but it knows that newCar is a car because you declared it that way.

(By the way, the Java convention is for class names, like car and vehicle, to start with upper-case letters.)

2 Comments

Question about this which is probably easy but what happens if I have more than one car? I will just have a bunch of newCar's in their appropriate spot in the array but what if I needed to sort them. Would that cause any issues if all my car objects are named newCar? I like the solution of making sure the compiler knows my vehicle is a car which I thought I was doing by declaring vehicleLot[i] = new car(owner, address, phone, email, convertible, color);. In your updated code it is explicitly assigning a car to that element which makes sense but what did my code do then?
I need to read more into this now. I am just more curious as to why when I created my object and assigned its reference to the element in the array why it didn't know it was a car.
1

It seems like you missed an intricate detail regarding polymorphism, you can put a Car Object into a Vehicle array(Due to Polymorphism) and on calling methods on the arrayElements the correct overloaded method is called (if you have overloaded it ie is ) , But since there is no getColor(); in your Vehicle class it doesn't work , suppose you had written a getColor() in Vehicle Class and overloaded it in the Car class ,

Then had you said

Vehicle v=new Car(); 
v.getColor();

The Car's getColor() will be called , However ,Please Note that the Compiler first checks if the vehicle class has the method , only then it checks if the actual object type and calls the overloaded method belonging to the car class , But in your case the first test fails and an error is thrown Try Reading about Polymorphism and Run-time Binding in Java

4 Comments

very good explanation about the compile time error. We are just learning about dynamic binding and polymorphism so I'm still in the baby stages of researching and learning about it.
@Stevenfowler16 glad it helped ! now is the right time to also learning good naming conventions and design practices ,.
Yeah the naming was a mistake I had it capitalized but then I thought it loked funny so I went back to lowercase. I'll end up commenting it all out when I get done. Do you do yours during the program?
@Stevenfowler16 what do you mean commenting it all out ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.