Let's understand what kind of types in Java are and how they differ from each other.
Java is a strictly typed programming language and it has both primitive (simple) types and non-primitive (reference) types.
Primitive types are like the building blocks of data in Java. They directly store the actual values in memory, like numbers or single characters. They do not have fancy methods or functions that you can call on them. However, non-primitive types are more complex and can represent more sophisticated data structures. They don't store the actual data directly; instead, they store references (like memory addresses) to where it is stored. For example, If you have a String variable, it doesn't hold the actual characters of the string; instead, it holds a reference to where those characters are stored in memory.
While working with simple types, you do simple operations directly, like adding or subtracting two int values. Also, They have default values, even if you don't set them explicitly. For instance, if you declare an int without assigning a value, it's automatically set to 0. But, non-primitive types often come in methods or functions that you can use to perform operations on the data. If you declare a reference type without assigning a value, it defaults to null (which simply means it's not pointing to anything in memory).
Now, it's time to understand object-oriented programming (OOP). All object-oriented programming languages provide mechanisms that help you implement the object-oriented model. They are encapsulation, inheritance, polymorphism, and abstraction. Let’s take a look at these concepts now.
Encapsulation is the mechanism that binds together code and the data it manipulates and keeps both safe from outside interference and misuse. One way to think about encapsulation is a protective wrapper that prevents the code and data from being randomly accessed by other codes defined outside the wrapper.
Second comes Inheritance and it is the process by which one object acquires the properties of another object. This is important because it supports the concept of hierarchical classification. For example, a Golden Retriever is part of the classification dog, which in turn is part of the mammal class, which is under the larger class animal. Without the use of hierarchies, each object would need to define all of its characteristics explicitly. However, by use of inheritance, an object needs only to define those qualities that make it unique within its class, as it can inherit its general attributes from its parent.
The third pillar is Polymorphism (from Greek, meaning “many forms”), which is a feature that allows one interface to be used for a general class of actions. Consider a stack. You might have a program that requires three types of stacks. One stack is used for integer values, one for floating-point values, and one for characters. The algorithm that implements each stack is the same, even though the data being stored differs. In a non–non-object-oriented language, you would be required to create three different sets of stack routines, with each set using different names. However, because of polymorphism, in Java, you can specify a general set of stack routines that all share the same names.
And finally, it's time for Abstraction, which in some literature is not even considered a pillar. Humans manage complexity through abstraction. For example, people do not think of a car as a set of tens of thousands of individual parts. They think of it as a well-defined object with its own unique behavior. This abstraction allows people to use a car to drive to the grocery store without being overwhelmed by the complexity of the parts that form the car. They can ignore the details of how the engine, transmission, and braking systems work. Instead, they are free to utilize the object as a whole