Inheritance is one of the core principles of object-oriented programming (OOP), which help us derive a class from another class or a hierarchy of classes that share a set of attributes and methods. In other words, it is a relationship between a superclass (a more generalised class) and a subclass (a more specialised class), where the subclass inherits data and behavior from the superclass.
In Java, abstraction is implemented using abstract class and interface, which are two categories in Java with different rules and properties. An abstract class appears similar to any other class, but it is declared with the abstract keyword, and one can never instantiate an abstract class.
Learning Object-Oriented Programming is essential for modern software development as it introduces many features such as Inheritance, Encapsulation, Abstraction, and Polymorphism. Besides reducing code complexity, the oops provide other advantages like code modularity, code reusability, code extensibility, data hiding, etc.
The word “interface” means a medium or means of communication between two entities. Similarly, in Java, interfaces are used to ease the communication between various classes. An interface looks similar to any class and contains only constants, method signatures, default methods, and static methods.
An exception is an event that occurs during the execution of a program and disrupts the normal (expected) flow of the program. The word “exception” in programming refers to an “exceptional event.” As soon as the exception is thrown, the runtime system attempts to find an exception handler.
In OOP, Polymorphism allows us to code to an interface and has multiple implementations, making the program better. In Java, there are two types of polymorphism: Compile-time and Runtime polymorphism. The first type is implemented with method overloading, and the second one is implemented via method overriding.
In C++, there are a few differences between structure and class based on their definition and use cases. One major difference is that the structure members and base classes are public by default, and the members and base classes of a class are private by default.
Operator overloading is a compile-time polymorphism in C++ that allows us to make operators work for user-defined data types as objects and structures. In other words, we can extend the meaning of an operator to operate on a user-defined data type.
The Dependency Inversion Principle (DIP) states that high-level modules should not depend on low-level modules; both should depend on abstractions. This abstraction removes the direct dependency on the details, decoupling it and thus allows for easier re-use of the important functionality in the policy.
Java language has a feature called method overloading, which allows multiple methods within a class to have the same name with different argument lists. It is a type of polymorphism (the process by which we can perform a single task in various ways). To be more concise, overloading is an example of static polymorphism.
The Interface Segregation Principle states that a client should never be forced to depend on methods it does not use. We achieve this by making our interfaces small and focused**. It would be best to split large interfaces into more specific ones focused on a particular set of functionalities so that the clients can choose to depend only on the functionalities they need.
In oops, we may want our object to get initialized with some specific properties, or we may need to do some operations every time an object is instantiated. To do such things, we use constructors. In simple words, a constructor is defined inside the class that contains the code to instantiate the class object.
A class is a user-defined blueprint that describes what a specific kind of object will look like, but an object is an instance of a class, which contains data and methods working on that data. In simple words, classes and objects are the fundamental building blocks of Object-Oriented Programming (OOPS).
In OOPS, Abstraction exposes necessary functionality to external objects and hides implementation details. This helps programmers to use complex logic without understanding its implementation. In other words, Abstraction is a process of exposing relevant functionalities so that one needs to know what the code does, not how it does it.
Encapsulation is one of the fundamental concepts in OOP that bundles data and associated methods that operate on that data into a single block called class. It is also a pathway for restricting direct access to some data and methods associated with a class (which leads to data hiding).
There might be some objects common to all parts of the program, and we require a single instance of it. The Singleton is a creational design pattern that ensures that a class has only one instance throughout the application. This instance is accessible from any part of the application with global access.
Object-Oriented Programming binds together the data and the methods in the form of an object and selectively exposes the data to other objects. It primarily revolves around classes and objects, i.e., their definition, instantiation, relationship, communication, etc. It helps us to organize code and development processes for large-scale software.
According to the Liskov Substitution principle, an object of a parent/base class must be interchangeable with an object of a child/derived class without changing the program. So the subclass objects should behave in the same way as the superclass objects. In simple words, LSP is all about well-designed inheritance.
The factory method is a creational design pattern in which we define a superclass for creating an object but let the subclasses decide which class to instantiate. Therefore, the factory method enables a class to delegate instantiation to its subclasses and eliminates the coupling of concrete products to the Client code.
Abstract Factory is a creational design pattern that helps in providing an interface for producing families of related objects (products) without specifying their concrete classes. It is a hierarchy of classes that encapsulate many possible “platforms” and provide an interface for the construction of a suite of “products” or “features” in software development.
In object-oriented programming, the open-closed principle states: software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification"; that is, such an entity can extend its behavior without modifying its source code. This principle allows us to use the power of abstraction and inheritance to create such systems.
To write clear and maintainable code, software engineering principles are recommendations that programmers should follow during software development. It is a set of approaches and best practices introduced by some famous industry experts and authors. This blog will go through some popular software engineering principles for developing quality software.
The single responsibility principle is one of the popular SOLID principles in software engineering that determines how we should modularize code in object-oriented programming. The idea for this principle is relatively simple: it makes our software easier to implement and prevents unexpected side-effects of future changes.
This blog has discussed critical C++ concepts related to dangling pointers, bad pointers, memory leak, static memory, dynamic memory, reference variable, const and volatile keywords, template, etc.
Modern Softwares usually consists of millions of lines of code and operates on terabytes of data, and is so complex that not a single person understands it all. Hence we need a way to organize these instructions so that it is: Easier to understand and explain, Easier to reuse and extend, Easier to maintain. And Object-Oriented Programming(OOP) has been one of the most popular paradigms used in the last few decades for this purpose.
Subscribe to get weekly content on data structure and algorithms, machine learning, system design and oops.