Vehicle, Components and Car relationship I am writing Vehicle - Components - Car relationship.
I have to separate cars that use the diesel, petrol and electric engines because each of them produce their own results (but methods of each are the same).

For example, if car is using diesel engine (which obviously should have only diesel exhaust system) then it produces higher pollution than electric car's engine.

It is very important that after I could set the engine, for example my Car has diesel engine and now I want to use electric instead because of lower pollution.

Right now, I have an abstract class Vehicle. Vehicle has-a components such as Engine and Tires. Car is-a (extends) Vehicle.

Vehicle.class

public abstract class Vehicle {
    private Engine engine;
    private Tire tires;

    public Engine getEngine() {
        return engine;
    }

    public void setEngine(Engine engine) {
        this.engine = engine;
    }

    public Tire getTires() {
        return tires;
    }

    public void setTires(Tire tires) {
        this.tires = tires;
    }

    public MotorVehicle() {
        super();
    }

    public Vehicle(Engine engine, Tire tires) {
        this.engine = engine;
        this.tires = tires;
    }
}


Car.class

public class Car extends Vehicle {
    private Engine engine;
    private Tire tires;
    private ExhaustSystem system;

    public Car() {
        super();
    }

    public Car(Engine engine, Tire tires) {
        super(engine, tires);
    }
}


Where Engine.class is an interface

public interface Engine {
    String getType();
    ExhaustSystem getExhaustSystem();
}


and, for example, DieselEngine.class implements it

public class DieselEngine implements Engine {
    private String type;
    private DieselExhaustSystem system;

    public DieselEngine(String type, DieselExhaustSystem system) {
        this.type = type;
        this.system = system;
    }

    @Override
    public String getType() {
        return type;
    }
    @Override
    public ExhaustSystem getExhaustSystem() {
        return system;
    }
}


Similar to Engine - ExhaustSystem.class is an interface 

public interface ExhaustSystem {
    double getGasExits();
}


and DieselExhaustSystem.class implements it.

public class DieselExhaustSystem implements ExhaustSystem {

    /**
     *
     * @return CO2 emission units.
     */
    @Override
    public double getGasExits() {
        return 3;
    }
}


I also will have Truck which will extend Vehicle.

After I wrote this, I have some doubts about its correctness.

The main question is:


Is relationship and classes logic correct?


If not or partially not, then:


What can be done better?
Maybe I do not understand polymorphism?
Maybe I do not understand has-a / is-a relationships?
Maybe I should use another desing pattern for my task (for example, bridge pattern)?
Perhaps it is better to make Engine abstract and other engines extend it?
Thanks for sharing your code.



OOP doesn't mean to "split up" code into random classes.

The ultimate goal of OOP is to reduce code duplication, improve readability and support reuse as well as extending the code.

Doing OOP means that you follow certain principles which are (among others):


information hiding / encapsulation
single responsibility
separation of concerns
KISS (Keep it simple (and) stupid.)
DRY (Don't repeat yourself.)
"Tell! Don't ask."
Law of demeter ("Don't talk to strangers!")




We create a new class if we need to implement new behavior not yet present nor belonging to any existing class.  

In your example the class Car does not (yet) add any new behavior neither to the class Vehicle which it extends nor to the program as a whole. Therefore it is not needed (as well as your planned class Truck) and Vehicle should not be abstract. If you need to identify different vehicle types you might introduce a vehicleType property of type String...