Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wants static but can't support?

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;
    }
}
like image 517
Seth T Avatar asked Dec 22 '22 16:12

Seth T


2 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!

like image 55
George Avatar answered Dec 26 '22 11:12

George


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.

like image 24
Nathan Hughes Avatar answered Dec 26 '22 11:12

Nathan Hughes