Four Fundamental Pillars of Object-Oriented Programming (OOP)

Published on 22 October 2024 | by Santosh Kumar Tripathi

What are the pliers of OOP?

eAPI

  • Encapsulation:- Binding into a single structure – Class (Method & Data Structure)
  • Abstraction:- using Access Modifier, Hiding implementation & exposing relevant and essential data
  • Polymorphism:- Use an entity in many forms – Overriding (Run Time/dynamic/Late binding – Use virtual & override keywords) & Overloading (Compile Time/Static/Early binding, but not true because if you change the method name everything breaks from the design point of view.)
  • Inheritance:- Reusability of code & eliminates redundant code. Driving new from a class - Instance. Parent-child relationship.

What is the difference between abstraction and encapsulation?

Encapsulation

Abstraction

Encapsulation hides variables or some implementation that may be changed so often in a class to prevent outsiders access it directly. They must access it via getter and setter methods.

Abstraction is used to hide something too, but to a higher degree (class, interface). Clients who use an abstract class (or interface) do not care about what it is, they just need to know what it can do.

Encapsulation solves the problem at the implementation level.

Abstraction solves the problem at the design level.

Abstraction is used for hiding unwanted data and giving only relevant data.

Encapsulation is hiding the code and data into a single unit to protect the data from the outer world.

Abstraction is set to focus on the object instead of how it does it.

Encapsulation means hiding the internal details or mechanics of how an object does something.

Abstraction is the outer layout in terms of design.

Encapsulation is the inner layout in terms of implementation.

What is method overloading?

Method overloading is creating multiple methods with the same name with unique signatures in the same class. When we compile, the compiler uses overload resolution to determine the specific method to be invoked.

overloading can be done for both the method and the constructor.

What are the different ways a method can be overloaded?

Methods can be overloaded using different data types for the parameter, different order of parameters, and a different number of parameters.

What is method overriding?

Overriding is a concept where a method in a derived class uses the same name, return type, and arguments as a method in its base class. In other words, if the derived class contains its implementation of the method rather than using the method in the base class, the process is called overriding.

How is method overriding different from method overloading?

When overriding a method, you change the behaviour of the method for the derived class. Overloading a method simply involves having another method with the same name and different signatures within the class.

  • Runtime Polymorphism (Called Late Binding or Overriding or Dynamic Binding)
  • Compile Time Polymorphism (Called Early Binding or Overloading or Static Binding)

What is inheritance?

Inheritance represents the relationship between two classes where one type derives functionality from a second type and then extends it by adding new methods, properties, events, fields and constants.

C# supports two types of inheritance:

  • Implementation inheritance
  • Interface inheritance

What are implementation and interface inheritance?

When a class (type) is derived from another class (type) such that it inherits all the members of the base type it is Implementation Inheritance.

When a type (class or a struct) inherits only the signatures of the functions from another type it is Interface Inheritance.

In general, Classes can be derived from another class, hence supporting Implementation inheritance. At the same time, Classes can also be derived from one or more interfaces. Hence they support Interface inheritance.

What is inheritance hierarchy?

The class which derives functionality from a base class is called a derived class. A derived class can also act as a base class for another class. Thus it is possible to create a tree-like structure that illustrates the relationship between all related classes. This structure is known as the inheritance hierarchy.

When should you use inheritance?

Inheritance is a good choice when:

  • Your inheritance hierarchy represents an "is-a" relationship and not a "has-a" relationship.
  • You can reuse code from the base classes.
  • You need to apply the same class and methods to different data types.
  • The class hierarchy is reasonably shallow(deep), and other developers are not likely to add many more levels.
  • You want to make global changes to derived classes by changing a base class.

What is an interface class?

Aninterfaceclass has only public abstract members, such as properties and procedures, which classes and structures can implement. The interface defines only the signatures of the members and not their definition (internal workings). These abstract methods must be implemented in the inherited classes.

Why can’t you specify the accessibility modifier for methods inside the interface?

In an interface, we have virtual methods that do not have a method definition. All the methods are there to be overridden in the derived class. That’s why they all are public. Must use a public or internal keyword from the interface.

What’s the difference between an interface and an abstract class?

Interface

Abstract Class

Interfaces have all the methods having only declarations but no definition.

In an abstract class, we can have some concrete methods.

In an interface class, all the methods are

public.

An abstract class may have private methods.

By creating an interface, you can move your implementation to any class that implements

your interface.

By creating an abstract class, you can share implementations for all derived classes in one

central place, and avoid lots of bad things like code duplication.

When you can fully describe the concept in

terms of "what it does" without needing to

specify any of "how it does it", then you should use an interface.

If you need to include some implementation

details, then you will need to represent your

concept in an abstract class

Are there many classes that can be "grouped" and described by onenoun? If so, have an

abstract class by the name of this noun, and

inherit the classes from it

What kinds ofverbscan be applied to my class

that might in general also be applied to others.

Create an interface for each of these verbs.

If the same thing can be achieved via an abstract class then why do we need an interface?

This will break the interface segregation of the SOLID principle.

Define Constructors?

A Constructor is a special method in a class/struct with the same name as that of a class/struct without any return type, used to initialize (Construct) fields and members of a class/struct. The constructor is automatically invoked whenever an object class is created.


public class mySampleClass
 {
public mySampleClass()
{ // This is the constructor method. }
// rest of the class members goes here.
}

How is a Constructor called?

A constructor can only be called by:

  • Compiler using New keyword to initialize a class/struct.
  • Another constructor of the same class/struct using: this() keyword.
  • Constructors of derived class using: base() keyword.

mySampleClass obj = new mySampleClass()

Type of Constructors?

  • Default Constructor
  • Parameterized Constructor
  • Copy Constructor
  • Static Constructor
  • Private Constructor
  • Instance Constructor

What is a Default constructor?

Every public class has a default constructor. This is inserted by the C# compiler and is not shown in the C# code. It receives no parameters. It has no internal logic. It is removed if you add an explicit constructor.

You can eliminate the default constructor from a class by specifying a private constructor, which eliminates the external creation of the type.

What is a Parameterized constructor?

A constructor with at least one parameter is called aparameterizedconstructor. The advantage of aparameterized constructor is that you can initialize each instance of the class to different values.


public class car
{
public car(string drive)
{ }

public car(int NoOfLights)
{ }
}

What is a copy constructor?

C# doesn't provide a copy constructor for objects, but you can write one yourself. The constructor whichcreates an object by copying variables from another object is called a copy constructor. The purpose of a copy constructor is to initialize a new instance to the values of an existing instance.


public class Person
{
public int Age { get; set; }
public string Name { get; set; }

// Copy Constructor
public Person(Person previousPerson)
{
Name = previousPerson.Name;
Age = previousPerson.Age;
}

// Parameterized Constructor
public Person(string name, int age)
{
Name = name;
Age = age;
}
}

What is a static constructor?

A static constructor is used to initialize anystaticdata, or to perform a particular action that needs to be performed once only.

  • A static constructor cannot be called directly.
  • If a static constructor throws an exception, the runtime will not invoke it a second time, and the type will remain uninitialized for the lifetime of the application domain in which your program is running.
  • A static constructor is used when you want to ensure that some static state is initialized before it is accessed.
  • There can be only one static constructor in the class.
  • The static constructor should be without parameters.
  • There should be no access modifier in the static constructor definition.
  • It can only access the static members of the class.

public class MySampleClass
{
static readonly long Baseline;

static MySampleClass()
{
Baseline = DateTime.Now.Ticks;
}
}

Can we access static members from the non-static (normal) constructors?

Yes we can.

What is a private constructor?

The declaration of the empty constructor prevents the automatic generation of a default constructor. A private constructor can enforcethe singleton design concept.

What is an instance constructor?

Instance constructors are used to create and initialise instance member variables when you use thenewexpression to create an object of aclass. Instance constructors can also be used to call the instance constructors of base classes.

An instance constructor is called whenever an object of the class is created. It is called explicitly. The instance constructor takes parameters. It has access specifiers.

What is an abstract modifier in C#?

The abstractmodifier indicates that the thing is being modified has a missing or incomplete implementation. The abstract modifier can be used with classes, methods, properties, indexers, and events. Use theabstractmodifier in a class declaration to indicate that a class is intended only to be a base class of other classes. Members marked as abstract or included in an abstract class must be implemented by classes that derive from the abstract class.


abstract class ShapesClass
{
abstract public int Area();
}

class Square : ShapesClass
{
int side = 0;

public Square(int n)
{
side = n;
}

// Area method is required to avoid a compile-time error.
public override int Area()
{
return side * side;
}
}

What are the features of an abstract modifier?

Abstract classes
  • An abstract class cannot be instantiated because it doesn't have a public constructor. so can not create a new instance. The abstract class gives information about the behaviour but there is no implementation.
  • An abstract class may contain abstract methods and accessors.
  • It is not possible to modify an abstract class with thesealedmodifier because a sealedmodifier prevents a class from being inherited but theabstractmodifier requires a class to be inherited.
  • A non-abstract class derived from an abstract class must include actual implementations of all inherited abstract methods and accessors.
  • An abstract class must provide an implementation for all interface members.
  • An abstract class can be inherited from a class and one or more interfaces.
  • An abstract class can have constructors and destructors.
Abstract method or property

why the abstract class cannot have a constructor?

(MSDN) Abstract types should not have constructors. Constructors on abstract types can be called only by derived types. Because public constructors create instances of a type, and you cannot create instances of an abstract type, an abstract type that has a public constructor is incorrectly designed.

To fix a violation of this rule, either make the constructor protected or do not declare the type as abstract.

When do you have to declare a class as abstract?

  • When the class itself is inherited from an abstract class, not all base abstract methods have been overridden.
  • When at least one of the methods in the class is abstract.

What is a static modifier?

Static class: A static class is the same as a non-static class; the only difference is it cannot be instantiated. In other words, you cannot use the new keyword to create a variable of the class type, because there is no instance variable. Static classes are automatically sealed, so people can't inherit and override their behaviour. There is something special in the IL. Static classes are marked both abstract and sealed (which cannot be otherwise done from C#) which prevents instantiation.

You can access the members of a static class by using the class name itself. For example,

DAOBranch.GetInstance().GetBranchByID(intID);

A static class can be used as a convenient container for sets of methods that just operate on input parameters and do not have to get or set any internal instance fields. For example, in the .NET Framework Class Library, the static System.Math class contains methods that perform mathematical operations, without any requirement to store or retrieve data that is unique to a particular instance of the Math class.

Main features of a static class:

  • Contains only static members.
  • Cannot be instantiated.
  • Is sealed (Static classes are automatically marked both abstract and sealed in IL).
  • Cannot contain Instance Constructors.

Static classes are sealed and therefore cannot be inherited. They cannot inherit from any class except Object.

Static Methods:

A non-static class can contain static methods, fields, properties, or events. The static member is callable on a class even when no instance of the class has been created. The static member is always accessed by the class name, not the instance name. Only one copy of a static member exists, regardless of how many instances of the class are created.

Static methods can be overloaded but not overridden, because they belong to the class, and not to any instance of the class.

To access a static class member, use the name of the class instead of a variable name to specify the location of the member, as shown in the following example:

Automobile.Drive();

int i = Automobile.NumberOfWheels;

What is an override modifier?

The override modifier is required to extend or modify the abstract or virtual implementation of an inherited method, property, indexer, or event. The method that is overridden by an override declaration is known as the overridden base method. The overridden base method must have the same signature as the override method.

You cannot override a non-virtual or static method. The overridden base method must be virtual, abstract, Override or overridden.

What is a const modifier?

The const keyword is used to modify a declaration of a field or local variable. It specifies that the value of the field or the local variable is constant, which means it cannot be modified.

  • A constant expression must yield a value of the target type or of a type that can be implicitly converted to the target type.
  • A constant expression is an expression that can be fully evaluated at compile time. Therefore, the only possible values for constants of reference types are string and null.
  • The static modifier is not allowed in a constant declaration. aconstfield is essentially static in its behaviour. It belongs to the type, not to instances of the type.
  • A constant can participate in a constant expression, as follows

public const int c1 = 5;

public const int c2 = c1 + 100;

What is the difference between const, readonly and static?

  • Constant: - Constant fields must be assigned a value at the time of declaration and after that, they cannot be modified. Whenever you declare a constant variable, the C# compiler substitutes its value directly into the Intermediate Language (MSIL). By default, constants are static, hence you cannot define a constant type as static. A const field is a compile-time constant. A constant field can be initialized with a constant expression which must be fully evaluated at compile time.
  • You can apply the const keyword to built-in value types. Constants can be marked as public, private, protected, internal, or protected internal access modifiers. Use the const modifier when you are sure that the value of a field or local variable will not be changed.

    • Readonly: - A readonly field can be initialized either at the time of declaration or within the constructor of the same class. Therefore, readonly fields can be used for run-time constants. Explicitly, you can specify a readonly field as static since like constant by default it is not static. Readonly keywords can be applied to a value type and reference type (which is initialized by using the new keyword). Also, the delegate and event could not be readonly. Use the readonly modifier when you want to make a field constant at runtime.
    • Static: - The static keyword is used to specify a static member, which means static members are common to all the objects and they do not tie to a specific object. This keyword can be used with classes, fields, methods, properties, operators, events, and constructors, but it cannot be used with indexers, destructors, or types other than classes.

    What is a virtual modifier?

    the virtual keyword is used to modify a method, property, indexer, or event declaration and allow for it to be overridden in a derived class.

    • When a virtual method is invoked, the run-time type of the object is checked for an overriding member. The overriding member in the most derived class is called, which might be the original member if no derived class has overridden the member.
    • By default, methods are non-virtual. You cannot override a non-virtual method.
    • You cannot use the virtual modifier with the field, static field, abstract, private, or override modifiers. Because Virtual properties behave like abstract methods, except for the differences in declaration and invocation syntax.
    • Method, property and events can be virtual.

    Can a private virtual method be overridden?

    Answer: No, because private methods are not accessible outside the class.

    What is a base class and a derived class?

    A class is a template for creating an object. The class from which other classes derive fundamental functionality is called a base class. E.g. If ClassY derives from Class X, then Class X is a base class.

    The class which derives functionality from a base class is called a derived class. If Class Y derives from Class X, then Class Y is a derived class.

    What are the access keywords?

    base: Accesses the members of the base class within a derived class:

    • Call a method on the base class that has been overridden by another method.
    • Specify which base-class constructor should be called when creating instances of the derived class.
    • A base class access is permitted only in a constructor, an instance method, or an instance property accessor.
    • It is an error to use thebasekeyword from within a static method.
    
    base.GetInfo();
    
    // 'this': Refers to the current instance of the class. 
    // The keyword refers to the current instance of the class.
    // Used to qualify members hidden by similar names.
    
    public class Employee
    {
        private string name;
        private string alias;
    
        public Employee(string name, string alias)
        {
            // Use 'this' to qualify the fields, name and alias:
            this.name = name;
            this.alias = alias;
        }
    }
    

    To pass an object as a parameter to other methods, for example

    CalcTax(this);

    To declare indexers, for example

    
    public int this[int param]
    {
        get { return array[param]; }
        set { array[param] = value; }
    }
    

    Can “this” be used within a static method?

    We can’t use ‘This’ in a static method because we can only use static variables/methods in a static method. Static methods don’t have instance variables.

    What is a nullable type?

    A value type cannot be assigned a null value. Nullable types allow you to assign null to value-type variables. You can declare nullable types using Nullable<t> where T is a type. A nullable type int is the same as an ordinary int plus a flag that says whether the int has a value or not (is null or not). Here compiler treats "null" as a valid value.

    For example, say I have a Stored Procedure that accepts two parameters @A and @B. It gives me back one out Parameter @C.

    This output Parameter can be Null also. So in that case we should use a Nullable Variable which can take Null also as allowed values.

    What are the Characteristics of Nullable Types?

    • Nullable types can only be used with value types.
    • The Value property will throw an InvalidOperationException if the value is null; otherwise, it will return the value.
    • The HasValue property returns true if the variable contains a value, or false if it is null.
    • You can only use == and != operators with a nullable type. For other comparisons use the Nullable static class.
    • Nested nullable types are not allowed. Nullable<Nullable<int>> i; will give a compile-time error.
    • a Nullable<Int32>, pronounced "Nullable of Int32," can be assigned any value from -2147483648 to 2147483647, or it can be assigned the null value.

    What Different Types of Operations on this Nullable Type and Expected Results?

    • A Nullable Type is incompatible with a General Data Type. This means that we can not have an operation between a nullable type and a general datatype. For example
    
    int? x = 4;
    int y = 3;
    
    // Compile-time error: Cannot implicitly convert type 'int?' to 'int'.
    // An explicit conversion exists (are you missing a cast?)
    int z = x * y;
    
    Console.WriteLine(z.ToString());
    Console.ReadLine();
    
    • To avoid this error we need to declare all the variables as Nullable like in the following code:
    
    int? x = 4;
    int? y = 3;
    int? z = x * y;
    
    Console.WriteLine(z.ToString());
    Console.ReadLine();
    
    // This program works fine with no compile-time and runtime errors.
    
    • No operation of a nullable Type is possible with a not-nullable type. But we can always compare a Nullable Type with a Not Nullable type.
    
    int? x = 3;
    int y = 3;
    bool check = false;
    
    if (x == y) // Nullable int (x) is compared with non-nullable int (y)
    {
        check = true;
        Console.WriteLine(check.ToString());
        Console.ReadLine();
    }
    

    The above code snippet works fine with no error and prints the value of the check as true.

    • The above code snippet works fine with the "!=" operator also.
    • null coalescing operator: This operator in C# is represented as "??". Look at the following code snippet for a better understanding of this operator.
    
    int? x = null;
    int y = 4;
    int? result;
    
    result = x ?? y; // If x is null, use y as the value.
    
    Console.WriteLine(result.ToString());
    Console.ReadLine();
    

    Look at the statement: result = x ?? y; This operator assigned the value of "x" to" result " if "x" is null else it will assign the value of "y" to "result". So if the first variable is null then that value will be assigned else the value of the second variable will be assigned. As expected in the above case "result" will hold Null.

    Caution: As the variable "result" can also have null, therefore it should be defined as Nullable Type.

    • Assigning Nullable Type variable Value to a Not Nullable Type: Directly assigning Nullable Type Variable Value to a Not Nullable Type Variable is illegal.
    
    int? x = 4;
    int y = x; // Compile-time error: Cannot implicitly convert 'int?' to 'int'
    
    Console.WriteLine(y.ToString());
    Console.ReadLine();
    

    This code snippet will generate the following compile-time error: Error 1 Cannot implicitly convert type 'int?' to 'int'. An explicit conversion exists (are you missing a cast?)

    But there is a workaround for this with the help of a null coalescing operator.

    
    int? x = 4;
    int y = x ?? 0; // If x is null, assign 0; otherwise, assign x's value
    
    Console.WriteLine(y.ToString());
    Console.ReadLine();
    

    Now if you run this program, y will have a value of x i.e. 4. In place of 0 in the statement int y = x ?? 0; you can use any integer.

    What is shadowing?

    There are two ways of shadowing either through a scope or through inheritance. Hiding a method of child class and giving a new implementation is known as shadowing from inheritance.

    Shadowing through inheritance is the default when a derived class implements a method of the base class that is not declared as overridden in the base class. The derived class member’s signature, return type, and access level may differ from the base class. Shadowing can be obtained by using the new keyword. Shadowing is one of the different concepts of polymorphism’s concepts.

    Well, there are two types of Polymorphism as stated below:

    • Static Polymorphism (Early binding)
    • Dynamic Polymorphism (Late binding)