Encapsulation is about hiding internal data and only exposing what's necessary. You protect your class's fields by making them private and control access through public getters and setters. Think of it like a vending machine — you press a button to get a snack, you don't reach inside and grab it yourself.
In an interview context: encapsulation protects data integrity, prevents outside code from putting your object in a bad state, and makes your code easier to maintain.
Every model class in your Spring Boot projects — User, Tournament, Transaction in TEnmo — used encapsulation. Private fields, public getters/setters. You've been doing this already.
Inheritance allows a class to inherit fields and methods from a parent class, avoiding code duplication. The child class gets everything the parent has, and can add its own behavior on top. Think of it like a blueprint — a Vehicle blueprint covers the basics, then Car and Truck extend it with their own specifics. Key keywords are extends for classes and implements for interfaces.
In an interview context: inheritance promotes code reuse, establishes an "is-a" relationship (a Car IS-A Vehicle), and forms the foundation for polymorphism.
In My Work: In your Spring Boot projects, Spring's own class hierarchy uses inheritance heavily. Your REST controllers likely extended or used base classes. Also worth noting — your @Repository interfaces in TEnmo extended JpaRepository, which is inheritance giving you all those built-in database methods for free.
Summary: Polymorphism means one interface, many forms. The same method call behaves differently depending on which object is actually running it. There are two types — compile-time (method overloading) and runtime (method overriding). Runtime polymorphism is the more important one for interviews. Think of it like a universal remote — same button, different behavior depending on which device you're controlling.
In an interview context: polymorphism lets you write flexible code that works with a parent type but executes child-specific behavior automatically at runtime.
Overloading is when you use the same function name.
Summary: Abstraction means hiding complex implementation details and only showing what's necessary. You define WHAT something should do, without specifying HOW it does it. Java achieves this through abstract classes and interfaces. Think of it like driving a car — you know the steering wheel turns the car, you don't need to know how the steering column mechanically works underneath.
In an interview context: abstraction reduces complexity, enforces a contract that implementing classes must follow, and lets you swap implementations without breaking anything.
Abstraction is basically seeing functions and process ordered without seeing the internal logic. You could have a class object that stores all the information and then you as a programmer call the various methods. DAO's are absolutely a great example.