OOP Fundamentals: Classes, Objects, Instances & Methods for Professional Certification
Object-oriented programming (OOP) is a fundamental paradigm in modern software development. This learning guide prepares you specifically for professional certification exams and explains core concepts clearly with practical examples.
Why OOP? The Foundation
Imagine you’re building a car. You wouldn’t reinvent every bolt, wheel, and component from scratch. Instead, you use pre-made, reusable parts—tires, seats, engines—each with specific functions that work together. That’s how OOP works. It’s a programming paradigm that builds software from reusable, well-structured “building blocks” called objects. This makes software easier to maintain, extend, and understand.
The Core Distinction: Class vs Object (Instance)
This is the foundation. Once you grasp this, everything else falls into place.
Class (The Blueprint)
A class is an abstract blueprint or template. It defines which attributes (properties) and methods (capabilities) the objects created from it will have.
Example: The class Auto. The blueprint says: “A car has the attributes farbe, anzahlTueren, and leistungInPS. It can perform the methods bremsen() and beschleunigen().”
The class exists only once in your code.
Object / Instance (The Concrete Thing)
An object is a concrete instantiation of a class. It’s created at runtime from the class using the new keyword in languages like Java or C#.
Example: The object meinGolf is an instance of the Auto class. It has concrete attribute values: farbe = "blau", anzahlTueren = 5, leistungInPS = 150. The object deinA3 is another instance with different values: farbe = "schwarz", anzahlTueren = 3, leistungInPS = 120.
You can create any number of objects from a single class.
Simple Analogy
- Class = The blueprint for a house (defines that it has walls, doors, windows)
- Object = The actual built house (specific address, white walls, oak door)
// Java Example: Class vs Object
public class Auto {
// Attributes (properties)
private String farbe;
private int anzahlTueren;
private int leistungInPS;
// Constructor
public Auto(String farbe, int anzahlTueren, int leistungInPS) {
this.farbe = farbe;
this.anzahlTueren = anzahlTueren;
this.leistungInPS = leistungInPS;
}
// Methods (capabilities)
public void beschleunigen() {
System.out.println("Das " + farbe + "e Auto beschleunigt");
}
public void bremsen() {
System.out.println("Das " + farbe + "e Auto bremst");
}
// Getters and setters
public String getFarbe() { return farbe; }
public void setFarbe(String farbe) { this.farbe = farbe; }
public int getAnzahlTueren() { return anzahlTueren; }
public int getLeistungInPS() { return leistungInPS; }
}
// Creating objects (instantiation)
public class Main {
public static void main(String[] args) {
// Object 1
Auto meinGolf = new Auto("blau", 5, 150);
meinGolf.beschleunigen();
// Object 2
Auto deinA3 = new Auto("schwarz", 3, 120);
deinA3.bremsen();
System.out.println("Mein Golf: " + meinGolf.getFarbe() + ", " +
meinGolf.getAnzahlTueren() + " Türen, " +
meinGolf.getLeistungInPS() + " PS");
}
}
The Four Pillars of OOP
1. Encapsulation
What is it? Bundling data (attributes) and the code that manipulates that data (methods) into a single unit—the class. Access to the data is controlled by “hiding” it from the outside world.
How does it work? Attributes are typically declared as private, meaning code outside the class cannot directly access or modify meinGolf.leistungInPS. Access happens exclusively through public methods called getters and setters.
getLeistungInPS(): Returns the value (reading)setLeistungInPS(int neueLeistung): Changes the value (writing)
Why is this important?
- Control: The class can validate in the setter method, ensuring new values make sense (e.g.,
neueLeistungcannot be negative) - Maintainability: If internal representation changes (e.g., storing power in kW instead of PS), you only update the getter/setter methods, not all code that uses these values
- Data consistency: Prevents objects from entering invalid states
// Example of encapsulation
public class Bankkonto {
// Private attributes - not accessible from outside
private double kontostand;
private String kontonummer;
private String inhaber;
public Bankkonto(String kontonummer, String inhaber, double startbetrag) {
this.kontonummer = kontonummer;
this.inhaber = inhaber;
this.kontostand = Math.max(0, startbetrag); // Balance cannot be negative
}
// Getter - controlled read access
public double getKontostand() {
return kontostand;
}
// Setter - controlled write access with validation
public void setKontostand(double neuerKontostand) {
if (neuerKontostand >= 0) {
this.kontostand = neuerKontostand;
} else {
System.out.println("Fehler: Kontostand darf nicht negativ sein!");
}
}
// Business method with encapsulation
public void hebeGeldAb(double betrag) {
if (betrag > 0 && kontostand >= betrag) {
kontostand -= betrag;
System.out.println("Abhebung erfolgreich. Neuer Kontostand: " + kontostand);
} else {
System.out.println("Abhebung nicht möglich. Ungültiger Betrag oder unzureichendes Guthaben.");
}
}
public void zahleEin(double betrag) {
if (betrag > 0) {
kontostand += betrag;
System.out.println("Einzahlung erfolgreich. Neuer Kontostand: " + kontostand);
} else {
System.out.println("Einzahlung nicht möglich. Betrag muss positiv sein.");
}
}
}
2. Inheritance
What is it? The ability to define a new class (subclass or child class) based on an existing class (superclass or parent class). The subclass inherits all attributes and methods of the superclass.
Why do this? It avoids code duplication (the DRY principle: Don’t Repeat Yourself) and models hierarchical relationships.
Example:
- Superclass:
Fahrzeug(with attributesgeschwindigkeit,herstellerand methodbewege()) - Subclass:
Auto(inherits fromFahrzeugand adds its own attributeanzahlTueren) - Subclass:
Fahrrad(inherits fromFahrzeugand adds its own attributeanzahlGaenge)
An Auto object automatically has geschwindigkeit and can call bewege().
// Example of inheritance
// Superclass (base class)
public class Fahrzeug {
protected String hersteller;
protected int geschwindigkeit;
protected int baujahr;
public Fahrzeug(String hersteller, int baujahr) {
this.hersteller = hersteller;
this.baujahr = baujahr;
this.geschwindigkeit = 0;
}
public void beschleunigen(int increment) {
this.geschwindigkeit += increment;
System.out.println(hersteller + " beschleunigt auf " + geschwindigkeit + " km/h");
}
public void bremsen(int decrement) {
this.geschwindigkeit = Math.max(0, geschwindigkeit - decrement);
System.out.println(hersteller + " bremst auf " + geschwindigkeit + " km/h");
}
public void bewege() {
System.out.println("Das " + hersteller + " Fahrzeug bewegt sich mit " + geschwindigkeit + " km/h");
}
// Getters
public String getHersteller() { return hersteller; }
public int getGeschwindigkeit() { return geschwindigkeit; }
public int getBaujahr() { return baujahr; }
}
// Subclass 1
public class Auto extends Fahrzeug {
private int anzahlTueren;
private String kraftstoffart;
public Auto(String hersteller, int baujahr, int anzahlTueren, String kraftstoffart) {
super(hersteller, baujahr); // Call superclass constructor
this.anzahlTueren = anzahlTueren;
this.kraftstoffart = kraftstoffart;
}
// Own method of subclass
public void hupen() {
System.out.println("Das " + hersteller + " Auto hupt!");
}
// Override superclass method
@Override
public void bewege() {
System.out.println("Das " + anzahlTueren + "-türige " + hersteller +
" Auto fährt auf der Straße mit " + geschwindigkeit + " km/h");
}
// Getters
public int getAnzahlTueren() { return anzahlTueren; }
public String getKraftstoffart() { return kraftstoffart; }
}
// Subclass 2
public class Fahrrad extends Fahrzeug {
private int anzahlGaenge;
private String fahrzeugtyp = "Fahrrad";
public Fahrrad(String hersteller, int baujahr, int anzahlGaenge) {
super(hersteller, baujahr);
this.anzahlGaenge = anzahlGaenge;
}
// Own method
public void schalten(int gang) {
if (gang >= 1 && gang <= anzahlGaenge) {
System.out.println("Schalte in Gang " + gang);
} else {
System.out.println("Ungültiger Gang!");
}
}
// Override method
@Override
public void bewege() {
System.out.println("Das " + hersteller + " Fahrrad mit " + anzahlGaenge +
" Gängen bewegt sich mit " + geschwindigkeit + " km/h");
}
}
3. Polymorphism
What is it? The ability for an object of a subclass to be treated as an object of its parent class. Methods can be overridden in subclasses to implement specific behavior.
Example: The move() method is defined in the parent class Vehicle. In the Car class, it’s overridden to output “The car drives on the road.” In the Airplane class (which also inherits from Vehicle), it’s overridden to output “The airplane flies through the air.”
Benefit: Code that calls the move() method doesn’t need to know the concrete type (Car or Airplane). It simply calls move() on the object of type Vehicle. At runtime, the correct overridden method of the object’s actual class is executed automatically. This makes your code incredibly flexible.
// Example of polymorphism
public class PolymorphismDemo {
public static void main(String[] args) {
// Different vehicle objects
Vehicle myCar = new Car("VW", 2020, 4, "Gasoline");
Vehicle myBike = new Bicycle("Cube", 2021, 21);
Vehicle myMotorcycle = new Motorcycle("Yamaha", 2019, 600);
// Polymorphism: all are treated as Vehicle
Vehicle[] vehicles = {myCar, myBike, myMotorcycle};
// Dynamic binding: the correct method is called at runtime
for (Vehicle vehicle : vehicles) {
vehicle.accelerate(50);
vehicle.move(); // Calls the overridden method of each subclass
vehicle.brake(20);
System.out.println("---");
}
// Type checking and downcasting
for (Vehicle vehicle : vehicles) {
if (vehicle instanceof Car) {
Car car = (Car) vehicle; // Downcasting
car.honk();
} else if (vehicle instanceof Bicycle) {
Bicycle bike = (Bicycle) vehicle;
bike.shiftGear(5);
}
}
}
}
// Additional subclass for the example
class Motorcycle extends Vehicle {
private int displacement;
public Motorcycle(String manufacturer, int year, int displacement) {
super(manufacturer, year);
this.displacement = displacement;
}
@Override
public void move() {
System.out.println("The " + manufacturer + " motorcycle with " + displacement +
" cc travels at " + speed + " km/h");
}
public void wheelie() {
System.out.println("The " + manufacturer + " motorcycle does a wheelie!");
}
}
4. Abstraction
What is it? The principle of reducing complex reality to only the essential properties relevant to your context while hiding unnecessary details.
Example: When you model a car as a Car object, you focus on attributes like power and methods like brake(). The details of how the brake actually works—hydraulics, brake pads, and so on—are irrelevant for most programs and are “abstracted away.” You simply call brake().
Abstraction is achieved primarily through two mechanisms:
- Abstract classes: Classes that cannot be instantiated but serve as templates for other classes. They can define abstract methods (methods without a body that subclasses must implement).
- Interfaces: See the next section.
// Example of abstraction
// Abstract class
public abstract class Animal {
protected String name;
protected int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
// Concrete method
public void sleep() {
System.out.println(name + " is sleeping.");
}
public void eat() {
System.out.println(name + " is eating.");
}
// Abstract methods - must be implemented by subclasses
public abstract void makeSound();
public abstract void move();
// Getters
public String getName() { return name; }
public int getAge() { return age; }
}
// Concrete subclasses
public class Dog extends Animal {
private String breed;
public Dog(String name, int age, String breed) {
super(name, age);
this.breed = breed;
}
@Override
public void makeSound() {
System.out.println(name + " barks: Woof! Woof!");
}
@Override
public void move() {
System.out.println(name + " runs on four legs.");
}
public void fetch() {
System.out.println(name + " fetches the ball.");
}
}
public class Cat extends Animal {
private String furColor;
public Cat(String name, int age, String furColor) {
super(name, age);
this.furColor = furColor;
}
@Override
public void makeSound() {
System.out.println(name + " meows: Meow!");
}
@Override
public void move() {
System.out.println(name + " sneaks around.");
}
public void scratch() {
System.out.println(name + " scratches the scratching post.");
}
}
Key Object-Oriented Programming Terms
Attribute (Property)
A variable that describes a state or characteristic of an object (for example, color, age, balance).
Method
A function or procedure defined in a class that describes the behavior of an object (for example, pay(), printDocument()). A method call (or message) is an instruction to an object to execute a specific method (for example, myAccount.withdraw(50)).
Persistence
The permanent storage of an object’s state (its attribute values) so that the data persists beyond the program’s termination. This typically happens in a database or a file. An object itself only “lives” in RAM during program execution.
// Example of persistence
import java.io.*;
import java.util.*;
public class PersistenceExample {
// Save object
public static void saveAccount(BankAccount account, String filename) {
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename))) {
oos.writeObject(account);
System.out.println("Account saved to " + filename);
} catch (IOException e) {
System.out.println("Error saving: " + e.getMessage());
}
}
// Load object
public static BankAccount loadAccount(String filename) {
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filename))) {
BankAccount account = (BankAccount) ois.readObject();
System.out.println("Account loaded from " + filename);
return account;
} catch (IOException | ClassNotFoundException e) {
System.out.println("Error loading: " + e.getMessage());
return null;
}
}
public static void main(String[] args) {
BankAccount myAccount = new BankAccount("DE123456789", "John Doe", 1000.0);
myAccount.deposit(500.0);
// Save
saveAccount(myAccount, "account.ser");
// Load
BankAccount loadedAccount = loadAccount("account.ser");
if (loadedAccount != null) {
System.out.println("Loaded account - Balance: " + loadedAccount.getBalance());
}
}
}
// Serializable interface for persistence
class BankAccount implements Serializable {
private static final long serialVersionUID = 1L;
private double balance;
private String accountNumber;
private String holder;
// ... rest of implementation as above
}
Interface / API / Interface
(Note: This term has two meanings!)
-
In general: An interface (or API - Application Programming Interface) defines a contract, describing what something can do without specifying how it does it. It’s a collection of method signatures (name, parameters, return type).
-
As a language construct (
interface): A specific language construct in OOP languages that formally defines these contracts. A class implementing aninterfacemust implement all its defined methods (fill them with code).
The Difference: Class vs. Interface
| Feature | Class | Interface |
|---|---|---|
| What is it? | A blueprint for objects | A contract or specification for capabilities |
| Contains… | Implementation (code for methods), attributes, constructors | Only method signatures (name, parameters, return type) without implementation (no code body) |
| Keywords | class, extends (inheritance) | interface, implements (implementation) |
| Inheritance | A class can inherit from only one other class (single inheritance) | A class can implement multiple interfaces |
| Instantiation | Can be instantiated with new (create objects) | Cannot be instantiated |
| Purpose | Implement state and behavior | Prescribe behavior |
Analogy
- Class = A specific employee: “Max Mustermann, Software Developer” knows SAP and can write Java code (implementation)
- Interface = The job posting: “We’re looking for a Java developer with SAP experience.” It lists only the requirements (skills) the applicant must have
// Interface example
interface Fliegend {
void fliegen();
void landen();
}
interface Schwimmend {
void schwimmen();
void tauchen();
}
// Class implements multiple interfaces
public class Ente implements Fliegend, Schwimmend {
private String name;
public Ente(String name) {
this.name = name;
}
// Implement interface methods
@Override
public void fliegen() {
System.out.println(name + " fliegt in die Luft");
}
@Override
public void landen() {
System.out.println(name + " landet auf dem Wasser");
}
@Override
public void schwimmen() {
System.out.println(name + " schwimmt elegant");
}
@Override
public void tauchen() {
System.out.println(name + " taucht nach Fischen");
}
// Own method
public void quaken() {
System.out.println(name + " quakt: Quak! Quak!");
}
}
// Polymorphism with interfaces
public class InterfaceDemo {
public static void main(String[] args) {
Ente meineEnte = new Ente("Donald");
// Treat as duck
meineEnte.quaken();
// Treat as flying
Fliegend fliegendeEnte = meineEnte;
fliegendeEnte.fliegen();
fliegendeEnte.landen();
// Treat as swimming
Schwimmend schwimmendeEnte = meineEnte;
schwimmendeEnte.schwimmen();
schwimmendeEnte.tauchen();
}
}
The Difference: Class Library vs. Framework
This is an important conceptual distinction often tested in exams.
Class Library (Library / SDK)
- You control the flow. A library is a collection of pre-built classes and methods that you use in your code, whenever and however you see fit.
- Analogy: A toolbox. You’re building a shelf and grab a hammer from the box (
Hammerklasse.schlagZu()), then a saw (Saegeklasse.saege()). You decide the order and purpose. - Examples: Java Standard Library, Apache Commons, jQuery.
Framework
- The framework controls the flow. A framework is a fundamental skeleton or structure for a specific type of application. You fill in the predefined spots with your code. The framework calls your code (the Hollywood Principle: “Don’t call us, we’ll call you”).
- Analogy: The framework is a blueprint for an entire house with prefabricated walls and wiring. You only need to install outlets and pick wallpaper (add your code to predefined methods). The blueprint (the framework) determines the flow.
- Examples: Spring (Java), .NET Framework, Angular, React (web), JUnit (testing).
In short: You use a library. You work within a framework.
// Library vs. Framework example
// Library: You call the methods
import java.util.ArrayList;
import java.util.Collections;
public class BibliothekBeispiel {
public static void main(String[] args) {
// You determine the flow
ArrayList<String> namen = new ArrayList<>();
namen.add("Alice");
namen.add("Bob");
namen.add("Charlie");
// You use library methods when you want
Collections.sort(namen);
System.out.println("Sortierte Namen: " + namen);
}
}
// Framework: The framework calls your code
// Example with JUnit testing framework
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class FrameworkBeispiel {
@Test // The framework calls this method
public void testAddition() {
// You fill the predefined method with your code
int result = 2 + 3;
assertEquals(5, result, "2 + 3 sollte 5 ergeben");
}
@Test // Another method the framework calls
public void testSubtraction() {
int result = 10 - 4;
assertEquals(6, result, "10 - 4 sollte 6 ergeben");
}
}
Summary for the IHK Exam
- Class vs. Object: Blueprint vs. concrete thing
- The 4 Principles:
- Encapsulation: Hide data, provide controlled access
- Inheritance: Inherit properties and methods, avoid redundancy
- Polymorphism: Override methods to enable subtype-specific behavior
- Abstraction: Hide unnecessary details
- Interface vs. Class: Interface defines what, class defines how
- Library vs. Framework: You use the library, the framework uses you
Exam-Relevant Concepts
Important Distinctions
| Concept | Description | Exam-Relevant |
|---|---|---|
| Class | Blueprint for objects | ✅ |
| Object/Instance | Concrete manifestation of a class | ✅ |
| Attribute | Property of an object | ✅ |
| Method | Behavior of an object | ✅ |
| Inheritance | Code reuse through hierarchy | ✅ |
| Polymorphism | Multiplicity through overriding | ✅ |
| Encapsulation | Data hiding with getter/setter | ✅ |
| Abstraction | Complexity reduction | ✅ |
Typical Exam Questions
- Explain the difference between a class and an object
- Describe the four OOP principles
- Implement a simple inheritance hierarchy
- Explain encapsulation with getter/setter methods
- Distinguish between interface and class
- Compare library and framework
These fundamentals are essential to understanding modern software development and form the foundation for advanced concepts like design patterns, frameworks, and architectural principles.
Continue on the OOP Learning Path
The next article in the OOP learning path covers OOP Class Relationships: Association, Aggregation, Composition & Inheritance for IHK Exam — class relationships for the IHK exam.

