Saturday, April 17, 2021

What is the difference between Abstract Class and Interface in C#?


This is a very important question for interviews at all levels.

Common differences to remember,

  • An abstract class is a half defined class, Interface is fully abstract
  • An abstract class does not provide full abstract implementation but the Interface does
  • Multiple inheritances of an abstract class are not allowed but multiple interfaces are allowed
  • An abstract class can contain a method with implementation and fields but Interfaces are only allowed to declare methods and properties.
  • Access modifiers can be defined in an abstract class but Interface is by default public
  • An abstract class and methods require Abstract keyword to declare whereas in Interface it is Interface
  • In other words, an abstract class does not provide full abstraction but an Interface does

Common points to remember,

  • We can not create an object of both Abstract class and an Interface
  • An abstract class with all abstract member are similar to an Interface declaration

I hope this basic differences and common characteristics help you to understand the basics of both an Abstract class and an Interface.

For more details, you are welcome to visit the dedicated posts for each topic as given below,

Any doubts, confusion? feel free to drop your thoughts. 

Saturday, April 10, 2021

What is difference between Abstraction and Encapsulation?

Abstraction is about showing what is necessary to the client

Encapsulation is about hiding the complexity

Key Differences

  • Abstraction is about to show the only necessary, Encapsulation is about hiding complexity 
  • Abstraction is focusing on what to be done, Encapsulation is focusing on how it can be done.
  • Abstraction solves problems at the design level while Encapsulation solves problems at the implementation level
  • Abstraction can be achieved using Interface or Abstract class, Encapsulation is achieved through Access Modifiers (Private, Public, Protected, etc.)
  • Abstraction is to be achieved during the design level, while Encapsulation is achieved at the implementation level.

Importance of Abstraction

  • Abstraction imposes simplicity in the code
  • It hides the irrelevant details
  • Programmed can be partitioned into a different level and helps decouple the architecture
  • Provides flexibility across different types of objects

Importance of Encapsulation

  • Makes code more manageable and easy to change with new requirements
  • Makes coding easier by hiding the complexity to the client
  • This makes unit testing easy
  • It helps to change part of code rather than changing everything 
  • Makes code more readable and understandable to the client what it offers 


Thursday, April 8, 2021

SOLID | Dependency Inversion Principle (DIP)

 The dependency Inversion Principle, it states high level modules should not depend on low level modules. This is introduced by Robert C. Martin. 

Points to remember, 

  • High level and low level modules should depend upon abstractions 
  • and abstraction should not directly be dependent on the details but details should depend upon abstractions
  • Normally we have seen a project structure like
    • Presentation Layer - Business Layer - Data Access Layer (This is highly coupled) 
    • But introducing this principle suggests going with High Level Modules - Abstractions - Low Level Modules (This makes it loosely coupled)
    • So any changes to Low level should not affect directly to high level modules

Example,

will go first with Presentation Layer - Business Layer - Data Access Layer so,

public class BusinessLayer
{
        private DataAccessLayer dataAccessLayer;
        public BusinessLayer()
        {
                dataAccessLayer = new DataAccessLayer();
        }
        public void Save()
        {
                dataAccessLayer.Save();    
        }

public class DataAccessLayer
{
        public void Save()
        {
            //Method implementation
        }
}

Now, following the example, you see it is a strongly coupled and dependent architecture. Any change coming to DataAccessLayer would affect the existing implementation. 

In place, if we introduce another layer like Repository that acts as an abstraction to make this module a decoupled one. 

public class BusinessLayer
{
        //private DataAccessLayer dataAccessLayer;    This is commented to implement the abstraction
        private IRepositoryLayer repositoryLayer;
        public BusinessLayer(IRepositoryLayer repo)
        {
                repositoryLayer = repo;
        }
        public void Save()
        {
                repositoryLayer.Save();    
        }

public class DataAccessLayer : IRepositoryLayer        
{
        public void Save()
        {
            //Method implementation
        }
}

public interface IRepositoryLayer
{
        void Save();
}

Now, this works great to implement the Dependency Inversion Principle, We have inverted the dependency directly to an abstract layer, so both are loosely coupled, and if any change is coming up then it can be easily modified and even this makes unit testing the code more easily. 

In conclusion, as this is the last from SOLID principles, we have come across the basics of it and understanding with real world scenarios and examples. I hope anyone at glance would be able to grasp the foundation of principles. 

Any doubts or suggestions or thoughts are completely welcome, let me know if you want to know more in such simple language and examples. 

SOLID | Interface Segregation Principle (ISP)

Interface Segregation Principle (ISP), states "Clients should not be forced to depend upon interfaces that they do not use"

This is again introduced by Sir Robert D. Martin, while consulting at xerox.

Similar to the 

Single Responsibility Principle the goal of the Interface Segregation Principle is to reduce the side effects of frequent changes in the existing implementation. 

Points to remember,

  • No client needs to be forced to introduce with what is not necessary to them
  • Rather than using one fat interface, splitting into smaller and relevant interfaces are advisable

Case Study from Xerox,

  • Xerox created inhouse software to help printer system do tasks like stapling and faxing along with regular printer task
  • The whole system requires change from scratch up
  • That creates a whole lot of change and complexity

Example,

Below the interface is a one fat consisting of all the methods, now if something needs to introduce the whole implementation requires change and that is risky.

interface IPrint
{
        void Print();
        void Scan();
        void Fax();
}

We have solved this issue by separating SendEmail functionality from other classes to meet the Single Responsibility Principle.

The solution for the above example would,

interface IPrint
{
        void Print();
        void Scan();
}
interface IFax
{
        void Fax();
}

class Printer1: IPrint            //Only has the ability to Print 
{
        public void Print()
        {

        }
        public void Scan()
        {

        }

class Printer2: IPrint, IFax    //Printer ability to Print and Fax both
{
         public void Print()
        {

        }
        public void Scan()
        {

        }
         public void Fax()
        {

        }

We have separated the functionality by breaking it into interfaces rather than a single one. Now in Print1 that has the functionality of Print and Scan but not Fax so implementation, only IPrint interface will meet the goal. Printer2 is all in one so Print, Scan, and Fax functionality so along with IPrint we can have IFax interface to get the functionality of Fax in the same. 

Here we have separated the responsibilities as well as distributed the interface from a big fat to multiple interfaces and achieved a high level of abstraction.

SOLID | Liskov Substitution Principle (LSP)

Liskov Substitution Principle is introduced by Barbara Liskov. It is basically about the parent-child relationship (Inheritance) in Object-Oriented Design. the LSP states that if "When class S is a substitute of class T then an object of type T can be replaced by an object of type S without affecting the functionality of the existing implementation"

Points to remember,

  • Types can be replaced by their subtypes without altering the desirable properties of the program. 
  • It has often been related to a duck test, it says "If it is lookalike a duck, quacks like a duck, but needs batteries - you probably have the wrong abstraction"
  • Derived classes should be able to extend their base classes without altering the original implementation.

Example from previous posts,

public interface IEmployee
{
        void CalculateSalary(Employee employee);
}

public class PermenentEmployee: IEmployee
{
         public void CalculateSalary(Employee employee)
        {
              //Salary calculation and print the same
        }
}
public class ContractEmployee: IEmployee
{
         public void CalculateSalary(Employee employee)
        {
              //Salary calculation and print the same
        }
}
public class TemporaryEmployee: IEmployee
{
         public void CalculateSalary(Employee employee)
        {
              //Salary calculation and print the same
        }
}
public class InternEmployee: IEmployee                                    //InternType with Error
{
         public void CalculateSalary(Employee employee)
        {
            throw new NotImplementedException();                        //Violation of LSP 
        }
}

So here is a good example of the Open Closed Principle, but if we are talking about the Liskov then we are breaking our goal here. For example what if a new requirement suggests a new Employee type without the CalculateSalary method. Say we have an Intern type to be added in. Class InternEmployee needs to throw an exception as it does not have to do anything with that method. 

Modified example with Liskov Substitution Principle,

public abstract class Employee                                                    //Abstract class 
{
        public virtual void CalculateSalary(Employee employee)
        {
          
        }
}

public class PermenentEmployee: Employee
{
         public void CalculateSalary(Employee employee)
        {
              //Salary calculation and print the same
        }
}
public class ContractEmployee: Employee
{
         public void CalculateSalary(Employee employee)
        {
              //Salary calculation and print the same
        }
}
public class TemporaryEmployee: Employee
{
         public void CalculateSalary(Employee employee)
        {
              //Salary calculation and print the same
        }
}

public class InternEmployee: Employee
{
         //public void CalculateSalary(Employee employee)        //Not required to implement the same.
}

This is the example can have much more use of object oriented programming and I am stretching the same with other design patterns going forward in further posts. I will be explaining the alternative for Virtual method in base class. 

Happy learning!

Tuesday, April 6, 2021

SOLID | Open Closed Principle (OCP)

Open Closed Principle (OCP)

A class can be open for extension and closed for modification. 

Points to remember,  
  • Software needs to be flexible, saying that it should have the ability to accept the various changes
  • OCP helps to make application flexible enough to accept the new behavior rather than changing the old one
  • So new implementation would go in new classes and logic but nothing can be changed in the existing implementation
  • Helps to maintain the code easily without breaking the whole thing
  • The best way to remember is an electric adapter in your wall, once fitted it's close for modification but open for extension using an external adapter. 

Example with initial implementation of Employee class,

public class Employee
{
        public void CalculateSalary(Employee employee)
        {
              if(employee.Type == "Permenent")
                    //Salary calculation and print the same
              else if(employee.Type == "Contract")
                    //Salary calculation and print the same
        }
}

Now, the above class looks great as it has an Employee and it calculates salary based on their type of Permanent and Contract. And because it is not following the open closed principle adding a new EmployeeType would require a whole class to be changed. 

Now, Thinking the same example with Open Closed Principle,

public interface IEmployee
{
        void CalculateSalary(Employee employee);
}

public class PermenentEmployee: IEmployee
{
         public void CalculateSalary(Employee employee)
        {
              //Salary calculation and print the same
        }
}
public class ContractEmployee: IEmployee
{
         public void CalculateSalary(Employee employee)
        {
              //Salary calculation and print the same
        }
}
public class TemporaryEmployee: IEmployee
{
         public void CalculateSalary(Employee employee)
        {
              //Salary calculation and print the same
        }
}

Now, we have created an Interface and whole new classes to have the ability to create new Employee Types rather than changing the class all the time. Modifying existing implementation would not be a good idea at all. 

The interface IEmployee shares a common contract and that can be shared across derived classes. Now in this example also has a loop whole, let me know if you can find it another way. 

Why use the Open Closed principle?    

  • Software needs flexibility to change, and as per the above example if requirements are quite extending the same functionality then we can have a better approach toward the open-closed principle
  • It is also breaking another first princple of SOlID that is Single Responsibility, The above class had a multiple responsibility and we have devided that into their own territory so in future if anything comes up, no modification will be done in existing code
  • Maintenance becomes more convenient   

In conclusion, I would say, Open Closed Principle also requires implementation of Single Responsibility Principle, Breaking responsibilities from a single entity, and making a framework in a way that is open for extension and closed for modification meets the goal. 

Monday, April 5, 2021

SOLID | Single Responsibility Principle (SRP)

Single Responsibility Principle (SRP)

Introduced by Robert C. Martin, defines responsibility as a single reason to change the class.
  • A class should have only one job to do
  • It should have a single purpose to serve
  • By a single purpose and responsibility it does not mean to be a small class with limited members in it, it can have many but it should point to a single purpose. 
  • It helps to separate the classes at the first design phase so that the complexity can be reduced and can be more extensible

Example,

public class UserService
{
    //Create user
   public void CreateNewUser()
   {
        //New user creation implementation
        //Send an email alert
        SendEmail();
    }

    //Sending an email with user-created
    public void SendEmail()
    {
        //Email sending implementation
    }
}

A developer would only be able to understand only when he or she has a clear picture of what needs to be implemented according to the requirement. 

The above example shows two methods kind of user registration which registers the user and sends an alert email. The implementation is short and sweet to understand and it looks good at the first level. But as we are looking at the single responsibility principle you can have an idea of what is wrong with it. 

Let's redesign that with Single Responsibility Principle, 

public class UserService
{
    //Create user
   public void CreateNewUser()
   {
        //New user creation implementation
        
        //Send an email alert
        EmailService.SendEmail();
    }
}

public static class EmailService
{
    //Sending an email with user-created
    public void SendEmail()
    {
        //Email sending implementation
    }
}

Now, we have created a separate class for EmailService which can only contain email-related methods. UserService should have user related tasks in it. If SendEmail() method is part of the same service then at any other service if it needs to consume it would be a redundant code. At this level the same thing becomes reusable.
 

SOLID Design Principles

SOLID Design Principles

SOLID is an acronym for design principles, let's look at it
SOLID principles are a time-tested solution for software design problems. This principle helps to achieve loosely coupled code design.

Common problems in software architecture?

  • A poor architecture will develop bugs over time
  • the application requires to be altered for all the customization and future extensions
  • Once the application is ready and in production, over time it takes a lot of effort even for a simple task
  • Creating a single class with a lot of responsibility
  • Unnecessary dependency between classes
  • Redundant code

Why we should use SOLID design principles?

  • SOLID principles help to solve above listed common problems
  • Provides loosely coupled architecture
  • Classes can have their specific responsibility 
  • Rather than extending the one class using inheritance and abstraction, we can achieve the reusable environment
  • It stops affecting the existing functionality
  • It allows focusing more on abstraction 
We will go into detail in each dedicated post. Let me know if you have any suggestions or feedback.

Saturday, April 3, 2021

What is the difference between Interface and Abstract Class in C#?

Difference between Interface and Abstract Class

Below are the common points to be remembered,

  • Abstract classes can have abstract plus nonabstract methods while Interfaces all methods needs to be abstract only.
  • Abstract classes can have variables and method implementation whereas Interfaces are not allowed to declare variables and the methods are abstract only. (No implementation)
  • Abstract class members are private by default even they can be changed, In Interface it is public by default and you cannot change the same.
  • To declare abstract classes Abstract keyword is used, for Interface it is Interface
  • Abstract classes and Interfaces are not allowed to create an instance.
  • Abstract classes can have a constructor but Interface do not. 

Friday, April 2, 2021

C# Object Oriented Programming 101

I am trying to explain C# with Object-Oriented Programming in a much easy language with examples. To help out to clear basic thumb rules and doubts regarding the base principles.
  1. What is OOP (Object Oriented Programming)?

  2. Working with Classes and Objects

  3. Class Members

  4. Access Modifiers - Encapsulation



If you interested in more dedicated posts, you are welcome add it in comment section below and I will try to make it for you.

Happy Learning!

What is Interface?

The interface is used to achieve abstraction in C#. It can only contain method declarations and properties. It is a contract between two entities. 

I am using the same example from the previous post on Abstraction, to know more about what is abstraction you can visit the same post.

interface IBird        //Interface keyword to declare it
{
    void Sound();    //Only method signature
}

Points to remember,
  • Like abstract classes, no instance creation so no constructor is allowed.is allowed for Interfaces as well 
  • Declaring interface with I comes out of practice to identify the same. 
  • Interfaces can contain methods and properties but not fields
  • All members of interface are abstract and public, you do not need to use public access modifiers
  • Derived classes must have an implementation of Interface members, you do not require to use override keyword to implement the method like abstract classes
  • The interface provides security and standard contract 

class Dove: IBird                    //Inherited Interface
{
        public void Sound()        //interface method implementation
        {               
                Console.WriteLine("Coo Coo");
        }
 }

above is an implementation example of Interface IBird to Dove class. 


What is Abstraction in C#?

Abstraction is about showing what is necessary.

In C# we have abstract classes and abstract methods to achieve abstraction. 

  • Abstract Class is a restricted class or can say a half-defined class, so we can not create an instance of the class. To use this class it needs to be inherited.
  • Abstract Method can only be declared in abstract classes and it does not contain implementation like an Interface method declaration. Method implementation is a must to their derived classes.
  • An abstract class can also contain regular methods with abstract ones.
  • You cannot create an instance of an abstract class
  • An abstract class with all abstract methods will work as an Interface
  • An abstract class can not be declared as Sealed 


abstract class Bird
{
    public abstract void Sound();
    public virtual void Sleep()    //Virtual methods can have their primary implementation
    {
        //Implementation
    }
}

Bird bird = new Bird();    //This will throw an error saying cannot create an instance of an abstract class 

Abstract class needs to be Inherited to their derived class

class Dove: Bird
{
        public override void Sound()        //abstract method implementation
        {               
                Console.WriteLine("Coo Coo");
        }
        public override void Sleep()        //Virtual method can be overridden and have its own implementation
        {
                //
Implementation
        }
}


Abstract classes provide security and hide the complexity of the object so the object shows only necessary details to the client. Abstraction can also be achieved using Interfaces. Kindly refer dedicated topic on Interface to learn more.  

Thursday, April 1, 2021

Polymorphism (Static vs Dynamic Polymorphism)

Polymorphism means "many forms", also can be said "one interface and many functions"

Inheritance allows the use of parent class members, Polymorphism makes the same methods work in a different way. Means method signature remains the same but the implementation may vary according to the need.

There are two forms we can achieve polymorphism

  • Static Polymorphism
    • compile time
  • Dynamic Polymorphism
    • run time

In, Static Polymorphism we have the same method with multiple definitions. Method parameters or return types must differ to achieve polymorphism. 

class Print
{
    public void PrintNumber(int 
val)
    {
            Console.WriteLine(
val);
    }

    public void PrintNumber(string val)
    {
            Console.WriteLine(val);
    }
}

The above example contains the same method PrintNumber() with different parameters, so here we client is able to pass either int to string to print the same. This is called static polymorphism.


In Dynamic Polymorphism, With the help of Abstract classes and Virtual methods, you can achieve dynamic polymorphism. As we know Abstract classes have an abstract method that would require to declare an implementation in derived classes.

Point to remember,

  • Instance creation is not allowed of an abstract class
  • Abstract methods can be defined in abstract classes
  • Sealed classes can not be inherited hence you can not declare an abstract class as Sealed.

abstract class Bird
{
        public virtual void Sound()
        {
                Console.WriteLine("Bird Sound");
        }
}

class Dove : Bird
{
       
 public override void Sound()
        {               
                Console.WriteLine("Coo Coo");
        } 
}

class Rooster : Bird
{
       
 public override void Sound()
        {               
                Console.WriteLine("cock-a-doodle-doo");
        } 
}

//Calling class method

Bird myBird = new Bird();        //This will create a bird object
Bird myDove = new Dove();    //This will create a dove object
Bird myRooster = new Rooster(); //This will create a rooster object

//Calling their methods

myBird.Sound();          //This returns Bird Sound from base class
myDove.Sount();        // This returns Coo Coo from the Dove class
myRooster.Sound();    //This returns cock-a-doodle-doo from Rooster class

The above example contains an abstract class Bird and Primary method definition with a virtual keyword which allows its child class to override the same method and make its own implementation. This is called a dynamic polymorphism as at runtime object comes to know which one to call. 

When to use Polymorphism?

  • This allows reusability in code 
  • The class extension is allowed using Inheritence so no change in the existing implementation
  • Respective clients have their own method definition so it won't affect existing clients

C# Interview Prep: 100 Common Questions for 0-3 Years Experience

Common C# Interview Questions  Basics of C# Language: What is C#? C# (pronounced C sharp) is a modern, object-oriented programming language...