Wants static but can't support?

Viewed 67

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;
    }
}
4 Answers

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?

Related