0% found this document useful (0 votes)
22 views

Chapter 4 Object-Oriented Programming (OOP) Concepts

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views

Chapter 4 Object-Oriented Programming (OOP) Concepts

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 36

PROPOSED BY AZOBOU CEDRIC

Chapter 4: Object-Oriented Programming


(OOP) Concepts
Classes and objects in Java
In Java programming, classes and objects are fundamental concepts that form the
backbone of object-oriented programming (OOP). A class is a blueprint or template that defines
the structure and behavior of objects. It specifies the attributes (fields) and actions (methods)
that the objects created from it will possess. A class does not hold data itself, but rather
describes how objects of that class should behave. On the other hand, an object is an instance
of a class, created at runtime, which holds actual data and can invoke methods defined by the
class. The key distinction in Java is that while a class is a static definition, an object represents
a dynamic, individual entity with its own state. Java enforces the creation of objects from
classes, ensuring that all interactions are organized and manageable, allowing for reusability,
modularity, and better data encapsulation.

Defining classes and creating objects


In Java, defining classes and creating objects involves a few key steps. Below is an
example that demonstrates how to define a class and create objects.
Defining a Class
A class is defined using the class keyword, followed by the class name and its body,
which contains attributes (fields) and methods (functions).
Example:
// Define a class called Car
public class Car {
// Fields (attributes)
String make;
String model;
int year;

// Constructor to initialize the object


public Car(String make, String model, int year) {
this.make = make;
this.model = model;
this.year = year;

Page 1 of 36
PROPOSED BY AZOBOU CEDRIC

// Method (action) to display car details


public void displayDetails() {
System.out.println("Car Make: " + make);
System.out.println("Car Model: " + model);
System.out.println("Car Year: " + year);
}
}

Creating Objects
To create an object, you use the new keyword followed by the class constructor. The constructor
initializes the fields of the object.
public class Main {
public static void main(String[] args) {
// Creating objects of the Car class
Car car1 = new Car("Toyota", "Corolla", 2020);
Car car2 = new Car("Honda", "Civic", 2021);

// Calling the displayDetails method for each object


car1.displayDetails();
car2.displayDetails();
}
}
Explanation:
➢ Class Definition: In the Car class, the attributes (make, model, year) describe the properties
of a car, while the method displayDetails() defines an action that outputs the car's details.
➢ Constructor: The constructor Car(String make, String model, int year) initializes the object
when it is created.
➢ Creating Objects: In the Main class, two objects (car1 and car2) are created using the new
keyword and initialized with specific values.
Output:

Page 2 of 36
PROPOSED BY AZOBOU CEDRIC

Car Make: Toyota


Car Model: Corolla
Car Year: 2020
Car Make: Honda
Car Model: Civic
Car Year: 2021
In this example, car1 and car2 are objects of the Car class, each with its own values for make,
model, and year.

Remark about Java programming language


In Java, everything is treated as a class in the sense that all data types, functionality,
and structures in Java are organized around the concept of classes and objects. However, this
doesn't mean that every single element in Java is explicitly a class—rather, it means that Java
follows the object-oriented programming (OOP) paradigm, where classes serve as the
fundamental building blocks for creating and organizing both data and behavior. Here's how this
idea is reflected in Java:
1. Classes as Templates or Blueprints
➢ A class in Java is a blueprint for creating objects. It defines the properties (fields) and
behaviors (methods) that the objects created from the class will have. When you create an
object, you are instantiating a class.
➢ For example, you define a Car class with properties like make, model, and year. Each object
(like car1 or car2) created from the class will represent a specific car with its own values
for those properties.

2. Primitive Data Types and Wrapper Classes


➢ While Java has primitive types like int, char, boolean, etc., which are not classes, Java
provides wrapper classes for these primitives (e.g., Integer, Character, Boolean) that
allow them to be treated as objects. These wrapper classes allow primitive values to be
used in contexts where objects are required (e.g., with generics or collections).
➢ Example:
int number = 5; // primitive type
Integer numberObj = new Integer(5); // wrapper class (object)
3. Everything is Part of the Java Class Library
➢ All the core functionalities in Java, such as input/output handling, networking, string
manipulation, and collections, are part of the Java Standard Library, which is composed
of classes. Even things like files, streams, dates, and user interfaces are modeled
using classes.
➢ For example:

Page 3 of 36
PROPOSED BY AZOBOU CEDRIC

• The String class represents sequences of characters.


• The Scanner class is used for input from the console.
• The File class is used to represent files and directories.
4. The Java Runtime Environment (JRE) and the Java Virtual Machine (JVM)
➢ When you run a Java program, the Java Virtual Machine (JVM) loads and executes your
class files. Even built-in entities like the main method are part of a class structure.
➢ The main method, which is the entry point of any Java application, belongs to a class and
requires that class to be executed.
5. Everything You Create in Java is an Object
➢ When you create an instance of a class (an object), you're interacting with a "real-world"
entity represented by that class. In Java, objects are instances of user-defined classes
or predefined classes from the standard library. Even though you might use primitive
types, objects are used to wrap and manipulate them.
➢ Every instance (object) in Java is created from a class and contains both state (fields)
and behavior (methods).

6. The Special Case of the Object Class


➢ In Java, all classes (including user-defined and built-in classes) inherit from the Object
class, which is the root class in the class hierarchy. This means that everything in Java
is ultimately a subclass of the Object class, and every object in Java can call methods
defined in Object (like toString(), equals(), etc.).
Example of Everything Being a Class:
// Define a simple class
public class Car {
String make;
String model;

public Car(String make, String model) {


this.make = make;
this.model = model;
}

public void displayInfo() {


System.out.println("Car make: " + make + ", model: " + model);

Page 4 of 36
PROPOSED BY AZOBOU CEDRIC

public static void main(String[] args) {


// Create an instance (object) of the class
Car car1 = new Car("Toyota", "Camry");
car1.displayInfo();
}
}
In this example, the class Car defines the blueprint for car objects. The object car1 is an
instance of the Car class.
In summary, in Java, everything is organized around classes and objects because the
language is designed to follow object-oriented principles. Classes are the fundamental building
blocks used to create and manage data and behavior. Even though Java includes primitive types
for efficiency, it offers wrapper classes to make those types behave like objects when necessary.
Ultimately, in the world of Java, everything interacts with and is structured around the concept
of classes, ensuring consistency, modularity, and flexibility in code design.

Instances variables and methods


In Java, instance variables and methods are key components of a class. They define the
state and behavior of objects created from that class.

Instance Variables
An instance variable is a variable that is declared inside a class but outside any method,
constructor, or block. Each object created from the class has its own copy of the instance
variable. This means that instance variables represent the state of an object.
Characteristics of Instance Variables:
• They are associated with an object.
• Every object has its own set of instance variables.
• They can have different values for different objects created from the same class.
• Instance variables can have access modifiers like private, public, protected, or
package-private (default).
Example of Instance Variables:
public class Car {
// Instance variables

Page 5 of 36
PROPOSED BY AZOBOU CEDRIC

String make;
String model;
int year;

// Constructor to initialize the instance variables


public Car(String make, String model, int year) {
this.make = make;
this.model = model;
this.year = year;
}

// Method to display the car's details


public void displayDetails() {
System.out.println("Car Make: " + make);
System.out.println("Car Model: " + model);
System.out.println("Car Year: " + year);
}

public static void main(String[] args) {


// Creating objects of the Car class
Car car1 = new Car("Toyota", "Corolla", 2020);
Car car2 = new Car("Honda", "Civic", 2022);

// Displaying the details of each car


car1.displayDetails();
car2.displayDetails();
}
}
Explanation:

Page 6 of 36
PROPOSED BY AZOBOU CEDRIC

• Instance Variables: make, model, and year are instance variables. Each car object will
have its own values for these variables.
• When you create car1 and car2, each object has its own copy of the instance variables.

2. Methods
A method in Java is a block of code that performs a specific task. Methods can be
associated with the behavior of an object or can operate on the data contained in the instance
variables. Methods can access instance variables, and they define what an object can do.
Types of Methods:
• Instance Methods: Methods that operate on instance variables of an object.

• Static Methods: Methods that are associated with the class itself and do not operate on
instance variables.
Characteristics of Methods:
• Instance methods belong to an object and can access instance variables of the object.

• Static methods belong to the class and can access only static variables or call other
static methods.
Example of Instance Methods:
public class Car {
// Instance variables
String make;
String model;
int year;

// Constructor
public Car(String make, String model, int year) {
this.make = make;
this.model = model;
this.year = year;
}

// Instance method
public void displayDetails() {
System.out.println("Car Make: " + make);

Page 7 of 36
PROPOSED BY AZOBOU CEDRIC

System.out.println("Car Model: " + model);


System.out.println("Car Year: " + year);
}

// Instance method to change the car's year


public void updateYear(int newYear) {
this.year = newYear;
}

public static void main(String[] args) {


// Create an object of Car
Car car1 = new Car("Toyota", "Corolla", 2020);

// Call the method to display details


car1.displayDetails();

// Call the method to update the year


car1.updateYear(2023);

// Display the updated details


System.out.println("Updated details:");
car1.displayDetails();
}
}
Explanation:
➢ Instance Methods:
• displayDetails() is an instance method that operates on the instance variables (make,
model, year) of the object.
• updateYear(int newYear) is an instance method that updates the year instance
variable of the object.

Page 8 of 36
PROPOSED BY AZOBOU CEDRIC

Static Methods and Variables


In addition to instance variables and methods, Java allows you to define static variables
and static methods. These belong to the class itself, not to instances of the class.
Static Variables:
• Static variables are shared by all instances of the class. They belong to the class and
are common across all instances.
Static Methods:
• Static methods can only access static variables and call other static methods. They
cannot directly access instance variables or instance methods.
Example of Static Methods and Variables:
public class Car {
// Instance variables
String make;
String model;
int year;

// Static variable (shared among all instances)


static int carCount = 0;

// Constructor
public Car(String make, String model, int year) {
this.make = make;
this.model = model;
this.year = year;
carCount++; // Increment the car count each time a new car is created
}

// Instance method
public void displayDetails() {

Page 9 of 36
PROPOSED BY AZOBOU CEDRIC

System.out.println("Car Make: " + make);


System.out.println("Car Model: " + model);
System.out.println("Car Year: " + year);
}

// Static method to display the total number of cars


public static void displayCarCount() {
System.out.println("Total Cars: " + carCount);
}

public static void main(String[] args) {


// Create objects
Car car1 = new Car("Toyota", "Corolla", 2020);
Car car2 = new Car("Honda", "Civic", 2022);

// Call instance method


car1.displayDetails();

// Call static method


Car.displayCarCount(); // Accessing static method without an instance
}
}
Explanation:
• Static Variable: carCount is a static variable that tracks the number of Car objects
created. It is shared across all instances.
• Static Method: displayCarCount() is a static method that displays the total number of
cars created. It can be called using the class name Car.displayCarCount().
Output:
Car Make: Toyota
Car Model: Corolla

Page 10 of 36
PROPOSED BY AZOBOU CEDRIC

Car Year: 2020


Total Cars: 2
Summary:
• Instance Variables: Each object has its own instance variables (state). They are
declared inside the class but outside any method.
• Instance Methods: Methods that operate on instance variables and define the behavior
of objects.
• Static Variables and Methods: Belong to the class rather than any specific instance.
Static variables are shared across all instances, and static methods can be accessed
without creating an object.

Constructors (default and parameterized)


In Java, constructors are special methods used to initialize objects. When you create an
instance of a class, constructors are automatically called to set up the initial state of the object.
There are two types of constructors in Java:
➢ Default Constructor: A constructor that does not take any arguments. If no constructor
is defined in a class, Java provides a default no-argument constructor.
➢ Parameterized Constructor: A constructor that takes parameters and allows you to
initialize an object with specific values when it is created.
1. Default Constructor
The default constructor is automatically provided by Java if no constructors are defined in the
class. It initializes object attributes with default values:
• Numeric values (int, float, etc.) are set to 0.
• Object references are set to null.
• Boolean values are set to false.
If you explicitly define a constructor, the default constructor is no longer provided, and you'll
need to define one if you still want it.
Example of Default Constructor:
public class Car {
// Instance variables
String make;
String model;
int year;

Page 11 of 36
PROPOSED BY AZOBOU CEDRIC

// Default constructor
public Car() {
// Default initialization
this.make = "Unknown";
this.model = "Unknown";
this.year = 0;
}

// Method to display car details


public void displayDetails() {
System.out.println("Car Make: " + make);
System.out.println("Car Model: " + model);
System.out.println("Car Year: " + year);
}

public static void main(String[] args) {


// Creating an object using the default constructor
Car car1 = new Car();

// Displaying details of the car


car1.displayDetails(); // Car Make: Unknown, Car Model: Unknown, Car Year: 0
}
}
Explanation:
• Default Constructor: The constructor public Car() initializes the make, model, and year
variables with default values like "Unknown" and 0.
• When the Car car1 = new Car(); line is executed, the default constructor is called, and
the instance variables are set to default values.
Output:

Page 12 of 36
PROPOSED BY AZOBOU CEDRIC

Car Make: Unknown


Car Model: Unknown
Car Year: 0
Parameterized Constructor
A parameterized constructor allows you to pass values when creating an object, which can
then be used to initialize the object's state. This is useful when you want to create objects with
specific attributes.
Example of Parameterized Constructor:
public class Car {
// Instance variables
String make;
String model;
int year;

// Parameterized constructor
public Car(String make, String model, int year) {
this.make = make;
this.model = model;
this.year = year;
}

// Method to display car details


public void displayDetails() {
System.out.println("Car Make: " + make);
System.out.println("Car Model: " + model);
System.out.println("Car Year: " + year);
}

public static void main(String[] args) {


// Creating an object using the parameterized constructor

Page 13 of 36
PROPOSED BY AZOBOU CEDRIC

Car car1 = new Car("Toyota", "Corolla", 2020);


Car car2 = new Car("Honda", "Civic", 2022);

// Displaying details of the cars


car1.displayDetails(); // Car Make: Toyota, Car Model: Corolla, Car Year: 2020
car2.displayDetails(); // Car Make: Honda, Car Model: Civic, Car Year: 2022
}
}
Explanation:
• Parameterized Constructor: The constructor public Car(String make, String model, int
year) takes three parameters (make, model, year) and assigns them to the instance
variables of the object.
• When the objects car1 and car2 are created, the parameters passed during object
creation are used to initialize the object's state.
Output:
Car Make: Toyota
Car Model: Corolla
Car Year: 2020
Car Make: Honda
Car Model: Civic
Car Year: 2022

Constructor Overloading
Java allows constructor overloading, which means you can define multiple constructors with
different parameter lists. This provides flexibility in creating objects with different initialization
options.
Example of Constructor Overloading:
public class Car {
// Instance variables
String make;
String model;

Page 14 of 36
PROPOSED BY AZOBOU CEDRIC

int year;

// Default constructor
public Car() {
this.make = "Unknown";
this.model = "Unknown";
this.year = 0;
}

// Parameterized constructor
public Car(String make, String model, int year) {
this.make = make;
this.model = model;
this.year = year;
}

// Method to display car details


public void displayDetails() {
System.out.println("Car Make: " + make);
System.out.println("Car Model: " + model);
System.out.println("Car Year: " + year);
}

public static void main(String[] args) {


// Creating an object using the default constructor
Car car1 = new Car();
car1.displayDetails(); // Car Make: Unknown, Car Model: Unknown, Car Year: 0

// Creating an object using the parameterized constructor

Page 15 of 36
PROPOSED BY AZOBOU CEDRIC

Car car2 = new Car("Ford", "Focus", 2021);


car2.displayDetails(); // Car Make: Ford, Car Model: Focus, Car Year: 2021
}
}
Explanation:
• Constructor Overloading: The class Car has two constructors—one is the default
constructor, and the other is a parameterized constructor.
• Depending on how you instantiate the object, the corresponding constructor is called.
Output:
Car Make: Unknown
Car Model: Unknown
Car Year: 0
Car Make: Ford
Car Model: Focus
Car Year: 2021

Key Points:
• Default Constructor: A constructor with no parameters. If you don't explicitly define any
constructor, Java provides a default no-argument constructor.
• Parameterized Constructor: A constructor that accepts parameters and initializes the
object's fields with provided values.
• Constructor Overloading: You can define multiple constructors in the same class with
different parameters.
Summary:
• Constructors are special methods used to initialize objects in Java.
• Default constructors provide default values for instance variables, while
parameterized constructors allow you to set specific values when creating an object.
• Java also supports constructor overloading, where multiple constructors with different
parameters can be defined in a class to offer more flexibility in object creation.

Page 16 of 36
PROPOSED BY AZOBOU CEDRIC

Encapsulation
In Java, encapsulation is one of the fundamental principles of Object-Oriented
Programming (OOP). It refers to the practice of bundling the data (variables) and the methods
(functions) that operate on the data into a single unit, known as a class. Encapsulation also
involves restricting direct access to some of the object's components and providing controlled
access through getter and setter methods.
Access modifiers are used to implement encapsulation in Java. Access modifiers are used to
specify the level of access control for classes, methods, and variables. They determine how and
where a class, method, or variable can be accessed within the program. Additionally, getter and
setter methods are used to provide controlled access to the instance variables of a class.

Access Modifiers in Java


There are four main types of access modifiers in Java:

public
➢ The public access modifier allows the class, method, or variable to be accessed from
anywhere, inside or outside the package.
➢ It provides the broadest level of access.
private
➢ The private access modifier restricts access to the class, method, or variable only within
the same class.
➢ Private variables and methods cannot be accessed outside the class, even by objects
created from that class.
protected
➢ The protected access modifier allows access to the class, method, or variable within the
same package or by subclasses (even if they are in different packages).
➢ Protected members can be accessed in the same package and by subclass objects.
Default (Package-Private)
➢ If no access modifier is specified, the default access is applied. This means the class,
method, or variable is accessible only within the same package.
➢ It has package-private access, which is more restrictive than protected but less
restrictive than private.
Examples of Access Modifiers: Let’s define a class Person with various access modifiers
applied to its attributes and methods.
public class Person {
// Public variable - can be accessed anywhere
public String name;
// Private variable - can only be accessed within this class

Page 17 of 36
PROPOSED BY AZOBOU CEDRIC

private int age;


// Protected variable - can be accessed within the same package or in subclasses
protected String address;
// Default (Package-Private) variable - can only be accessed within the same package
String phoneNumber;
// Constructor
public Person(String name, int age, String address, String phoneNumber) {
this.name = name;
this.age = age;
this.address = address;
this.phoneNumber = phoneNumber;
}
// Public method - can be accessed anywhere
public void introduce() {
System.out.println("Hi, I am " + name + ", " + age + " years old, from " + address);
}
// Private method - can only be accessed within this class
private void secret() {
System.out.println("This is a private method.");
}
// Getter and Setter for private variable 'age'
public int getAge() {
return age;
}
public void setAge(int age) {
if (age >= 0) {
this.age = age;
}
}

Page 18 of 36
PROPOSED BY AZOBOU CEDRIC

// Getter and Setter for private variable 'phoneNumber'


public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
}
Explanation:
• name: Public variable that can be accessed anywhere.
• age: Private variable that can only be accessed within the Person class.
• address: Protected variable that can be accessed within the same package or by
subclasses.
• phoneNumber: Default (package-private) variable that can only be accessed within the
same package.
• introduce(): Public method that can be called anywhere.
• secret(): Private method that can only be called within the Person class.
• Getter and Setter Methods: These provide controlled access to the private variables,
allowing you to safely manipulate values without directly accessing the variables.

Getter and Setter Methods


➢ Getter methods are used to retrieve the value of a private variable.
➢ Setter methods are used to set or modify the value of a private variable.
➢ The main benefit of using getter and setter methods is to maintain encapsulation,
allowing you to control how the values are set and retrieved.
Example of Getter and Setter Methods:
public class Main {
public static void main(String[] args) {
// Create a new Person object
Person person = new Person("John", 25, "New York", "123-456-7890");

Page 19 of 36
PROPOSED BY AZOBOU CEDRIC

// Accessing public variable directly


System.out.println("Name: " + person.name);

// Using getter method for private variable 'age'


System.out.println("Age: " + person.getAge());

// Using setter method to update private variable 'age'


person.setAge(30);
System.out.println("Updated Age: " + person.getAge());

// Using getter and setter for private variable 'phoneNumber'


System.out.println("Phone Number: " + person.getPhoneNumber());
person.setPhoneNumber("987-654-3210");
System.out.println("Updated Phone Number: " + person.getPhoneNumber());

// Calling a public method


person.introduce();
}
}
Explanation:
• The getter method getAge() retrieves the value of the private age variable.
• The setter method setAge(int age) sets the value of the private age variable, but with a
check to ensure the value is non-negative.
• The getter method getPhoneNumber() retrieves the phoneNumber, and the setter
method setPhoneNumber() updates it.
Output of the Example:
Name: John
Age: 25
Updated Age: 30
Phone Number: 123-456-7890

Page 20 of 36
PROPOSED BY AZOBOU CEDRIC

Updated Phone Number: 987-654-3210


Hi, I am John, 30 years old, from New York

Benefits of Access Modifiers and Getter/Setter Methods


Access Modifiers:
• Encapsulation: By using access modifiers, you can control which parts of your code can
access certain class members (variables or methods). This helps protect data and
maintain integrity.
• Security: Sensitive data, like personal information or internal methods, can be hidden
using private access.
• Flexibility: protected and public access levels allow flexibility in how data is shared
between different classes and packages.
Getter/Setter Methods:
• Encapsulation: By providing getter and setter methods, you control how data is
accessed and modified. For example, you can enforce rules like validating input (e.g.,
setAge(int age) ensures the age is non-negative).
• Data Integrity: Direct access to instance variables is often discouraged, but getter and
setter methods allow you to enforce data validation or transformation when the variable
is accessed or updated.
• Maintainability: If you need to change the internal structure of your class (e.g., change
how data is stored), you only need to modify the getter and setter methods, which makes
your code more flexible and easier to maintain.
Summary:
• Access Modifiers:
o public: Accessible everywhere.
o private: Accessible only within the same class.
o protected: Accessible within the same package and by subclasses.
o Default: Accessible only within the same package.
• Getter and Setter Methods:
o Used to provide controlled access to private instance variables.
o Getters retrieve values, and setters modify values.
o They help in maintaining encapsulation, ensuring that objects interact with their
data in a controlled and predictable way.

Page 21 of 36
PROPOSED BY AZOBOU CEDRIC

Inheritance and polymorphism in java


Inheritance in Java
In Java, inheritance is a mechanism that allows one class (subclass) to inherit fields and
methods from another class (superclass). This helps promote code reusability and the creation
of hierarchical relationships between classes. The extends keyword is used to establish this
relationship, where a subclass extends a superclass to inherit its properties and behaviors.

Basic Concept of Inheritance


When a class extends another class:
• The subclass inherits all non-private fields and methods from the superclass.
• The subclass can access the inherited members unless they are overridden or hidden.
• The subclass can also add its own members (fields and methods).
Syntax of Inheritance
The syntax for creating a subclass using the extends keyword is as follows:
class Subclass extends Superclass {
// Additional fields and methods can be added here
}
Example: Simple Inheritance
Let’s create a simple example where we have a Vehicle class (superclass) and a Car class
(subclass) that extends Vehicle.
// Superclass (Parent class)
class Vehicle {
// Instance variables
String brand;
int year;

// Constructor of the superclass


public Vehicle(String brand, int year) {
this.brand = brand;
this.year = year;
}

// Method of the superclass

Page 22 of 36
PROPOSED BY AZOBOU CEDRIC

public void displayDetails() {


System.out.println("Brand: " + brand);
System.out.println("Year: " + year);
}
}

// Subclass (Child class) extends the superclass 'Vehicle'


class Car extends Vehicle {
// Additional instance variable for the subclass
int doors;

// Constructor of the subclass


public Car(String brand, int year, int doors) {
// Call the superclass constructor
super(brand, year);
this.doors = doors;
}

// Method of the subclass


public void displayCarDetails() {
// Call the method of the superclass
displayDetails();
System.out.println("Doors: " + doors);
}
}

public class Main {


public static void main(String[] args) {
// Create an object of the Car class (subclass)

Page 23 of 36
PROPOSED BY AZOBOU CEDRIC

Car myCar = new Car("Toyota", 2020, 4);

// Call the subclass method


myCar.displayCarDetails(); // This will also call the superclass method
}
}
Explanation of the Code:
➢ Vehicle class (Superclass):
• This class has two fields (brand and year), a constructor to initialize them, and a method
displayDetails() to display their values.
➢ Car class (Subclass):
• The Car class extends Vehicle using the extends keyword, meaning it inherits the brand
and year fields and the displayDetails() method.
• It also has an additional field doors to represent the number of doors for the car.
• The constructor of Car calls the constructor of Vehicle using the super keyword to
initialize the inherited fields.
• The displayCarDetails() method in the Car class calls the displayDetails() method from
the Vehicle class and then displays the doors field.
➢ super(): The super() keyword is used in the subclass constructor to call the constructor of
the superclass (Vehicle), which initializes the brand and year fields.
Output of the Example:
Brand: Toyota
Year: 2020
Doors: 4

Key Points:
➢ extends Keyword: Used to establish an inheritance relationship where a subclass
inherits from a superclass.
➢ super Keyword: Used to refer to the superclass’s constructor or methods. It helps in
calling the superclass’s constructor to initialize the inherited properties.
➢ Subclass Methods: The subclass can access and modify the fields and methods of the
superclass, and it can also define its own fields and methods.

Page 24 of 36
PROPOSED BY AZOBOU CEDRIC

Overriding Methods:
If the subclass wants to provide a specific implementation of a method that is already
defined in the superclass, it can override the method. The @Override annotation is used to
indicate method overriding.
// Superclass (Parent class)
class Vehicle {
public void startEngine() {
System.out.println("The vehicle's engine is starting...");
}
}

// Subclass (Child class)


class Car extends Vehicle {
@Override
public void startEngine() {
System.out.println("The car's engine is starting with a roar!");
}
}

public class Main {


public static void main(String[] args) {
// Create an object of the Car class
Car myCar = new Car();

// Call the overridden method


myCar.startEngine(); // Output: The car's engine is starting with a roar!
}
}
Summary:
• Inheritance in Java allows a class (subclass) to inherit properties and behaviors from
another class (superclass) using the extends keyword.
Page 25 of 36
PROPOSED BY AZOBOU CEDRIC

• super is used to refer to the superclass’s methods or constructors.


• The subclass can add its own fields and methods or override methods from the
superclass.

Dynamic method dispatch (runtime polymorphism)


Dynamic Method Dispatch (also known as Runtime Polymorphism) is a mechanism
in Java where a method call is resolved at runtime rather than at compile-time. This allows Java
to call the overridden method in the subclass, depending on the type of the object that is being
referred to at runtime.
Key Concepts:
1. Method Overriding: Dynamic method dispatch relies on method overriding, where a
subclass provides a specific implementation of a method that is already defined in the
superclass.
2. Reference Type vs. Object Type: At runtime, the actual method to be invoked depends
on the object type, not the reference type. Although a reference variable may be of a
superclass type, it can point to an object of a subclass, and the method from the
subclass will be invoked if overridden.
Example of Dynamic Method Dispatch:
Let’s consider an example where a superclass Animal has a method sound(), and two
subclasses Dog and Cat override this method to provide their specific implementations.
// Superclass (Parent class)
class Animal {
// Method in superclass
public void sound() {
System.out.println("Some generic animal sound");
}
}

// Subclass (Child class) Dog


class Dog extends Animal {
// Overriding sound method in Dog class
@Override
public void sound() {

Page 26 of 36
PROPOSED BY AZOBOU CEDRIC

System.out.println("Bark");
}
}

// Subclass (Child class) Cat


class Cat extends Animal {
// Overriding sound method in Cat class
@Override
public void sound() {
System.out.println("Meow");
}
}

public class Main {


public static void main(String[] args) {
// Reference of Animal type, but object of Dog
Animal myAnimal = new Dog();
myAnimal.sound(); // Outputs: Bark (Dog's sound method is called)

// Reference of Animal type, but object of Cat


myAnimal = new Cat();
myAnimal.sound(); // Outputs: Meow (Cat's sound method is called)
}
}
Explanation of the Code:
• Superclass Animal: Contains a method sound() that prints a generic message.
• Subclass Dog: Overrides the sound() method to print "Bark".
• Subclass Cat: Overrides the sound() method to print "Meow".
• In the Main class, we create a reference variable myAnimal of type Animal, but it refers
to objects of type Dog and Cat at different times.
Page 27 of 36
PROPOSED BY AZOBOU CEDRIC

• At runtime, the actual method that gets invoked is determined by the type of the object
that the reference points to, not the type of the reference variable.
Output:
Bark
Meow

How Dynamic Method Dispatch Works:


➢ In the example, myAnimal is of type Animal, but it is assigned an object of type Dog and
then an object of type Cat.
➢ When myAnimal.sound() is called:

• For the first object (a Dog), the sound() method of the Dog class is called, which
outputs "Bark".

• For the second object (a Cat), the sound() method of the Cat class is called,
which outputs "Meow".
➢ This is an example of runtime polymorphism, because the method to be invoked (Dog's
sound() or Cat's sound()) is determined dynamically at runtime based on the actual
object type, not the reference type.
Important Characteristics of Dynamic Method Dispatch:
➢ Runtime Polymorphism occurs when a subclass overrides a method of the superclass,
and the method call is resolved at runtime.
➢ The method signature (name, return type, and parameters) must be the same in both
the superclass and the subclass for overriding to occur.
➢ Method Overriding is necessary for dynamic dispatch. The overridden method in the
subclass must have the same method signature as in the superclass.

Why is Dynamic Method Dispatch Important?


• Flexibility: It allows objects to behave differently depending on their actual type at
runtime, providing more flexibility in program design.
• Extensibility: New subclasses can be added without modifying existing code. The
program can dynamically choose the appropriate method based on the object type.
• Code Reusability: Superclasses can define common methods, and subclasses can
override them to implement specialized behavior.
Example with Inheritance Chain:
Let’s extend the example to have a deeper inheritance chain:
// Superclass (Parent class)

Page 28 of 36
PROPOSED BY AZOBOU CEDRIC

class Animal {
public void sound() {
System.out.println("Animal sound");
}
}

// Subclass (Child class) Dog


class Dog extends Animal {
@Override
public void sound() {
System.out.println("Bark");
}
}

// Subclass (Child class) Bulldog, a type of Dog


class Bulldog extends Dog {
@Override
public void sound() {
System.out.println("Woof");
}
}

public class Main {


public static void main(String[] args) {
// Reference of Animal type, but object of Bulldog
Animal myAnimal = new Bulldog();
myAnimal.sound(); // Outputs: Woof (Bulldog's sound method is called)

// Reference of Animal type, but object of Dog

Page 29 of 36
PROPOSED BY AZOBOU CEDRIC

myAnimal = new Dog();


myAnimal.sound(); // Outputs: Bark (Dog's sound method is called)

// Reference of Animal type, but object of Animal


myAnimal = new Animal();
myAnimal.sound(); // Outputs: Animal sound (Animal's sound method is called)
}
}
Output:
Woof
Bark
Animal sound

Summary of Dynamic Method Dispatch (Runtime Polymorphism):


• Method overriding is the key to dynamic method dispatch in Java.
• The method call is determined by the actual object at runtime, even if the reference
type is of the superclass.
• It allows for flexible and dynamic behavior of objects, enabling runtime decisions
about which method to execute.
• Advantages: It improves maintainability, allows flexibility, and extensibility in object-
oriented programming.
This is how runtime polymorphism (dynamic method dispatch) enables Java to call the correct
overridden method dynamically based on the actual type of the object at runtime.

Abstraction and interface in Java


In Java, abstraction and interfaces are two fundamental concepts of Object-Oriented
Programming (OOP) that are used to hide the implementation details and expose only the
essential functionality to the user. Both abstraction and interfaces help in reducing complexity
and increasing flexibility in code.
Let’s dive deeper into each of them and their usage in Java.

Page 30 of 36
PROPOSED BY AZOBOU CEDRIC

Abstraction in Java
Abstraction is the concept of hiding the internal implementation details of an object and
exposing only the essential features. It helps in reducing complexity and allows focusing on what
the object does rather than how it does it.
Types of Abstraction:
1. Abstract Classes: A class that cannot be instantiated directly and can contain both
abstract (without implementation) and non-abstract (with implementation) methods.
2. Interfaces: A contract that defines a set of abstract methods, which must be
implemented by any class that chooses to implement the interface.
Key Points:
➢ An abstract class can have both abstract methods (without implementation) and
concrete methods (with implementation).
➢ An interface can only have abstract methods (prior to Java 8, but this has been
enhanced in later versions).
Abstract Class in Java

An abstract class is a class that cannot be instantiated on its own and must be
subclassed. It can contain abstract methods (methods without implementation) and non-
abstract methods (methods with implementation).

abstract class Animal {


// Abstract method (no implementation)
public abstract void sound();

// Regular method with implementation


public void sleep() {
System.out.println("The animal is sleeping");
}
}
Example of an Abstract Class:
abstract class Animal {
String name;

// Abstract method (no implementation)

Page 31 of 36
PROPOSED BY AZOBOU CEDRIC

public abstract void sound();

// Regular method with implementation


public void sleep() {
System.out.println(name + " is sleeping.");
}
}

class Dog extends Animal {


Dog(String name) {
this.name = name;
}

@Override
public void sound() {
System.out.println(name + " barks.");
}
}

class Cat extends Animal {


Cat(String name) {
this.name = name;
}

@Override
public void sound() {
System.out.println(name + " meows.");
}
}

Page 32 of 36
PROPOSED BY AZOBOU CEDRIC

public class Main {


public static void main(String[] args) {
Animal dog = new Dog("Buddy");
Animal cat = new Cat("Whiskers");

dog.sound(); // Output: Buddy barks.


dog.sleep(); // Output: Buddy is sleeping.

cat.sound(); // Output: Whiskers meows.


cat.sleep(); // Output: Whiskers is sleeping.
}
}
Key Points:
• Abstract Methods: Methods that are declared but not implemented in the abstract
class. Subclasses must provide implementations for these methods.
• Concrete Methods: Methods that have their implementation in the abstract class.
• Constructor: Abstract classes can have constructors, and subclasses can call them via
super().

Interface in Java
An interface in Java is a reference type, similar to a class, that can contain only abstract
methods (methods without implementation), though starting from Java 8, interfaces can have
default and static methods with implementations.
Key Characteristics of Interfaces:
➢ Abstract Methods: All methods in an interface are abstract by default (before Java 8).
➢ Default Methods: From Java 8, interfaces can have default methods with a body
(implementation).
➢ Static Methods: From Java 8, interfaces can have static methods.
➢ Multiple Implementations: A class can implement multiple interfaces, overcoming
Java's limitation of single inheritance for classes.
Syntax of an Interface:
Page 33 of 36
PROPOSED BY AZOBOU CEDRIC

interface Animal {
// Abstract method (no implementation)
void sound();

// Default method with implementation


default void sleep() {
System.out.println("The animal is sleeping");
}
}
Example of an Interface:
interface Animal {
// Abstract method (no implementation)
void sound();

// Default method (with implementation)


default void sleep() {
System.out.println("The animal is sleeping");
}
}

class Dog implements Animal {


@Override
public void sound() {
System.out.println("Dog barks");
}
}

class Cat implements Animal {


@Override

Page 34 of 36
PROPOSED BY AZOBOU CEDRIC

public void sound() {


System.out.println("Cat meows");
}
}

public class Main {


public static void main(String[] args) {
Animal dog = new Dog();
Animal cat = new Cat();

dog.sound(); // Output: Dog barks


dog.sleep(); // Output: The animal is sleeping

cat.sound(); // Output: Cat meows


cat.sleep(); // Output: The animal is sleeping
}
}
Key Points :
• Abstract Methods: In an interface, all methods are abstract by default, meaning they do
not have implementations. Implementing classes must provide the implementations.
• Default Methods: From Java 8 onwards, interfaces can have default methods with an
implementation, which helps avoid breaking existing classes when adding new methods
to interfaces.
• Multiple Inheritance: A class can implement multiple interfaces, allowing for a form of
multiple inheritance.
• No Constructors: Interfaces cannot have constructors, as they cannot be instantiated
directly.
• Static Methods: From Java 8, interfaces can also contain static methods with an
implementation.

Difference Between Abstract Class and Interface

Page 35 of 36
PROPOSED BY AZOBOU CEDRIC

Feature Abstract class Interface


Metods Can have both abstract and All methods are abstract by
non-abstract methods default (Java 8 allows default
and static methods)
Multiplie inheritance A class can extend only one A class can implement
abstract class multiple interfaces
Constructor Can have constructors Cannot have constructors
Access modifiers Methods can have access Methods in interfaces are
modifiers (private, public public by default
etc.)
Field Can have instance variables Can have only “static” ad
(fields) “final” variables (constants)
Default method Cannot have default Can have default methods
methods
Usage Used for classes Connot that Used for defining an contract
share common behavior that can be implemented by
any class.

When to Use Abstract Class vs. Interface


• Use an Abstract Class when:

o You have a common base class with some shared behavior (i.e., concrete
methods) and some abstract behavior (i.e., abstract methods).
o You want to provide a partial implementation of functionality, and subclasses
can inherit and override some of these methods.
• Use an Interface when:
o You want to define a contract that multiple classes should adhere to, regardless
of their place in the class hierarchy.
o You need to implement multiple inheritance (a class can implement multiple
interfaces).
As a conclusion:
• Abstraction helps you hide the complexity and show only the essential features. It can
be achieved using abstract classes and interfaces.
• Abstract classes allow a mix of abstract and concrete methods, whereas interfaces
provide a way to specify a contract that implementing classes must follow.
• Interfaces are often used when a class can implement more than one contract, whereas
abstract classes are used when common behavior is shared among classes.

Page 36 of 36

You might also like