6 OOP Concepts in Java With Examples
6 OOP Concepts in Java With Examples
1. Abstraction
2. Encapsulation
3. Inheritance
4. Polymorphism
5. Association
6. Aggregation
7. Composition
Java comes with specific code structures for each OOP principle. For example,
the extends keyword for inheritance or getter and setter methods for
encapsulation.
Learn more and try Raygun Crash Reporting free for 14 days.
Abstraction
Abstraction aims to hide complexity from the users and show them only the
relevant information. For example, if you want to drive a car, you don’t need to
know about its internal workings. The same is true of Java classes. You can hide
internal implementation details by using abstract classes or interfaces. On the
abstract level, you only need to define the method signatures (name and
parameter list) and let each class implement them in their own way.
Abstraction in Java:
Encapsulation
Encapsulation in Java:
Polymorphism
Polymorphism in Java:
The same method name is used several times.
Different methods of the same name can be called from the object.
All Java objects can be considered polymorphic (at the minimum, they are
of their own type and instances of the Object class).
Example of static polymorphism in Java is method overloading.
Example of dynamic polymorphism in Java is method overriding.
Inheritance
Inheritance makes it possible to create a child class that inherits the fields and
methods of the parent class. The child class can override the values and methods
of the parent class, however it’s not necessary. It can also add new data and
functionality to its parent. Parent classes are also called superclasses or base
classes, while child classes are known as subclasses or derived classes as well. Java
uses the extends keyword to implement the principle of inheritance in code.
Inheritance in Java:
A class (child class) can extend another class (parent class) by inheriting its
features.
Implements the DRY (Don’t Repeat Yourself) programming principle.
Improves code reusability.
Multilevel inheritance is allowed in Java (a child class can have its own child
class as well).
Multiple inheritances are not allowed in Java (a class can’t extend more
than one class).
Association
Besides the four main principles of OOP, Java also works with three further
concepts (association, aggregation, composition) you can make use of when
designing your programs. Aggregation is a special form of association,
while composition is a special form of aggregation.
Aggregation
Aggregation in Java:
One-directional association.
Represents a HAS-A relationship between two classes.
Only one class is dependent on the other.
Composition
Compositionis a stricter form of aggregation. It occurs when the two classes you
associate are mutually dependent on each other and can’t exist without each
other. For example, take a Car and an Engine class. A Car cannot run without
an Engine, while an Engine also can’t function without being built into a Car.
This kind of relationship between objects is also called a PART-OF relationship.
Composition in Java:
Abstraction
With abstraction, you can hide the internal workings of an object and only show
the features the user needs to know about. Java provides two ways to implement
abstraction: abstract classes and interfaces. With abstract classes, you can achieve
partial abstraction, while interfaces make total (100%) abstraction possible.
Abstract classes
In the example below, you can see an abstract class called Animal with two
abstract and one concrete method.
// concrete method
void label() {
System.out.println("Animal's data:");
}
}
Extend the Animal abstract class with two child classes: Bird and Fish. Both of
them set up their own functionality for the move() and eat() abstract methods.
void move() {
System.out.println("Moves by flying.");
}
void eat() {
System.out.println("Eats birdfood.");
}
}
class TestBird {
public static void main(String[] args) {
Animal myBird = new Bird();
myBird.label();
myBird.move();
myBird.eat();
}
}
class TestFish {
public static void main(String[] args) {
Animal myFish = new Fish();
myFish.label();
myFish.move();
myFish.eat();
}
}
In the console, the concrete method has been called from the Animal abstract
class, while the two abstract methods have been called from Bird() and Fish(),
respectively.
Interfaces
An interface is a 100% abstract class. It can have only static, final, and public fields
and abstract methods. It’s frequently referred to as a blueprint of a class as well.
Java interfaces allow us to implement multiple inheritance in our code, as a class
can implement any number of interfaces. Classes can access an interface using
the implements keyword.
interface Animal {
public void eat();
public void sound();
}
interface Bird {
int numberOfLegs = 2;
String outerCovering = "feather";
class TestEagle {
public static void main(String[] args) {
Eagle myEagle = new Eagle();
myEagle.eat();
myEagle.sound();
myEagle.fly();
Encapsulation
With encapsulation, you can protect the fields of a class. To do so, declare the
fields as private and providing access to them with getter and setter methods.
The Animal class below is fully encapsulated. It has three private fields and each
of them has its own set of getter and setter methods.
class Animal {
private String name;
private double averageWeight;
private int numberOfLegs;
// Getter methods
public String getName() {
return name;
}
public double getAverageWeight() {
return averageWeight;
}
public int getNumberOfLegs() {
return numberOfLegs;
}
// Setter methods
public void setName(String name) {
this.name = name;
}
public void setAverageWeight(double averageWeight) {
this.averageWeight = averageWeight;
}
public void setNumberOfLegs(int numberOfLegs) {
this.numberOfLegs = numberOfLegs;
}
}
The TestAnimal class first sets a value for each field with the setter methods,
then prints out the values using the getter methods.
public class TestAnimal {
public static void main(String[] args) {
Animal myAnimal = new Animal();
myAnimal.setName("Eagle");
myAnimal.setAverageWeight(1.5);
myAnimal.setNumberOfLegs(2);
Inheritance
Inheritance allows us to extend a class with child classes that inherit the fields and
methods of the parent class. It’s an excellent way to achieve code reusability. In
Java, we need to use the extends keyword to create a child class.
class Bird {
public String reproduction = "egg";
public String outerCovering = "feather";
class TestEagle {
public static void main(String[] args) {
Eagle myEagle = new Eagle();
myEagle.flyUp();
myEagle.flyDown();
}
}
You can see the console output below:
Polymorphism
Polymorphism makes it possible to use the same entity in different forms. In Java,
this means that you can declare several methods with the same name until they
are different in certain characteristics. Java provides us with two ways to
implement polymorphism: method overloading and method overriding.
Static polymorphism
Method overloading means that you can have several methods with the same
name within a class. However, the number, names, or types of their parameters
need to be different.
class Bird {
public void fly() {
System.out.println("The bird is flying.");
}
public void fly(int height) {
System.out.println("The bird is flying " + height +
" feet high.");
}
public void fly(String name, int height) {
System.out.println("The " + name + " is flying " +
height + " feet high.");
}
}
The test class instantiates a new Bird object and calls the fly() method three
times. Firstly, without parameters, secondly, with one integer parameter
for height, and thirdly, with two parameters for name and height.
class TestBird {
public static void main(String[] args) {
Bird myBird = new Bird();
myBird.fly();
myBird.fly(10000);
myBird.fly("eagle", 10000);
}
}
In the console, we can see that Java could have differentiated the three
polymorphic fly() methods:
Dynamic polymorphism
By using the method overriding feature of Java, you can override the methods of
a parent class from its child class.
class Animal {
public void eat() {
System.out.println("This animal eats insects.");
}
}
}
The TestBird class first instantiates a new Animal object and calls
its eat() method. Then, it also creates a Bird object and calls the
polymorphic eat() method again.
class TestBird {
public static void main(String[] args) {
Animal myAnimal = new Animal();
myAnimal.eat();
Conclusion
OOP concepts in Java define how to structure a Java problem more efficiently.
Do you have errors in your Java code? Add Raygun Error Monitoring in minutes
and detect every problem in your software as they happen.