We just touched the features of object oriented programming in our Java introduction section, let us try to understand them in detail now. These concepts are at the heart of Java programming. While learning these concepts, this section also explains the difference between Java which is an Object oriented programming and 'C' which is procedural oriented programming.
Though we have not seen any section that talk explicitly about encapsulation, we did learn about it implicitly. Yes, Class and object forms the core of the concept "Encapsulation". Encapsulation is a process of binding data and the code that acts on the data.
Let us recall the definition of class, all the variables (Data) defined in the class can only be accessed by using the methods (Methods has the code/logic that acts on the data) defined in that class. So, a class binds data and the methods together which is precisely Encapsulation. "Object" which is an instance of a class helps in accessing the data using the methods defined in that class.
Java has a concept of "Access specifiers" which controls the scope of the variables defined in the class, access specifier along with the concept of object helps in implementing strict encapsulation. We will see more about access specifier in the coming sections.
If you are not familiar with "C" language, you could very well skip this part and go to the next section. This section helps in understanding the true meaning of OOP. How is Java object oriented programming language different from "C" a procedural language.
There is no concept of encapsulation in C language. A variable defined inside a function cannot be accessed outside its function, on the other hand, a global variable can be accessed by anyone. There is no way we can control the access to a global variable to certain desired functions. With Java, it is a different story. We can use access specifiers to control data access.
Inheritance is one of the core concepts of object oriented programming. Inheritance, as the name says, means inheriting some of the properties from parents or grand parents. Java has the concept of sub-class and super-class, sub-class can inherit some of the properties (not all properties) of its super-class. A sub-class can also define its own specific properties, thus a sub-class has the inherited properties plus its own sub-class properties. If we were to compare inheritance with a real life example, a child inherits some of the features from his/her parents at the same time has some features specific to him.
Java provides access specifiers, that helps super class in restricting a sub-class from inheriting some of his features. So, anything that's declared as "private" will not be inherited by sub-class. We will see more about access specifier in the coming sections. The whole point of Inheritance is about "re-use", if a class has already implemented some functionality then others can just re-use it, they don't have to redo the same work.
Inheritance works on multiple levels. A sub-class ( Let us call it sb1) that inherited some of its properties from its super class (let us call it su1) can in turn act as a super class and let another class inherit its properties. Thus, a sub-class (sb2) inheriting properties from sb1 also, automatically inherits properties from su1, this could go on to any number of levels. But, Java does not allow multiple inheritance ( More than one super class), which means sb1 cannot inherit properties from su1 and su2. We discuss inheritance in more detail, in the coming section: understanding inheritance.
The literal form of polymorphism is "Many forms". Java supports the concept of "Overloading", which lets us define one or more methods with the same name provided their signature is different. When an overloaded method is called, Java compares the methods signature (Signature is nothing but, methods return type, argument list, argument type) and calls the appropriate overloaded method. We discuss overloading in detail, in the next section: understanding overloading.
Along with overloading Java supports another behavior called "overriding". Overriding is another form of polymorphism, we will learn more about overriding in the coming sections. Java also supports another behavior called run-time polymorphism, which means decision on which action to choose is taken at the run time. We will see more about run-time polymorphism in the coming section: understanding run-time polymorphism.
Text book meaning of "Abstraction in Java" is a way of exposing only the required/essential features and hiding the internal implementation details. The term abstraction is very loosely defined and the boundaries are not as clear. The concept of abstraction is used in most of the OOP concepts, for instance when we define a class, it hides a lot of details and only expose few methods/properties. Java supports features like "interface and abstract class", where the concept of abstraction is more clearly visible. We will see more about these 2 topics in coming sections: understanding abstract class. understanding interface.