From both the definitions, it gets concluded that,
Figure 1
Figure 2
Now, I have class like Hyundai and Toyota which are derived from a parent class called Car. Here, I have the car methods as follow:
- public class Cars
- {
-
- public string Wheel()
- {
- return "4 wheeler";
-
- }
- public string CheckAC()
- {
- return "AC is available";
- }
- public string CallFacility()
- {
- return "Call Facility supported";
- }
-
- }
Here, I have 2 types of cars which are inherited from Cars.
- using oops1;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
-
- namespace oops1
- {
- public class Hyundai : Cars
- {
-
- static void Main(string[] args)
- {
- Hyundai dust = new Hyundai();
-
- Console.WriteLine(dust.CallFacility());
- Console.WriteLine(dust.Wheel());
- Console.WriteLine(dust.CheckAC());
- Console.ReadLine();
-
-
- }
- }
-
-
- }
Now, it runs as expected and gives the following output .
Similarly, as Toyota is a car and it also inherits from Cars class.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
-
- namespace oops1
- {
- public class Toyota : Cars
- {
- public string DiscountPrice()
- {
- return "20% discount on buying Toyoya Cars";
- }
-
-
- static void Main(string[] args)
- {
- Toyota Toy = new Toyota();
-
- Console.WriteLine(Toy.CallFacility());
- Console.WriteLine(Toy.Wheel());
- Console.WriteLine(Toy.CheckAC());
- Console.WriteLine(Toy.DiscountPrice());
-
- Console.ReadLine();
-
-
- }
- }
- }
We need some methods which are common to both the classes but their implementation is different.
- PRICE()- Both have price but different price.
- TotalSeat()- Both have total seats but different no. of seats.
- colors()- Both cars are of different colour.
So, here are the options for implementing these methods in both classes.
- Can I go for a normal class?
- Should I use interface here?
- Can I use an abstract class?
- If we are taking class, then we can only write normal methods having common implementation there. But, this will not satisfy our requirement because we need separate implementations in both the classes. Thus, we will not go forward with Class.
If we go for interface, we can achieve our goal but it will be like this. First, I will declare n interface, as follows.
- interface IExtra
- {
- double price();
- int getTotalSeat();
- string colors();
- }
Now, let me first inherit the Toyota class from Cars class and IExtra interface class to achieve our goal.
The code is given below.
- namespace oops1
- {
- public class Toyota : Cars,IExtra
- {
- public string DiscountPrice()
- {
- return "20% discount on buying Toyoya Cars";
- }
- public double price()
- {
- return 1000000.00;
- }
- public int getTotalSeat()
- {
- return 5;
- }
- public string colors()
- {
- return "Red";
- }
-
- static void Main(string[] args)
- {
- Toyota Toy = new Toyota();
-
- Console.WriteLine(Toy.CallFacility());
- Console.WriteLine(Toy.Wheel());
- Console.WriteLine(Toy.CheckAC());
- Console.WriteLine(Toy.DiscountPrice());
- Console.WriteLine("Total ONRoad Price:"+ Toy.price());
- Console.WriteLine(Toy.getTotalSeat());
- Console.WriteLine(Toy.colors());
-
- Console.ReadLine();
-
-
- }
- }
So, the sketch diagram of this implementation will be like this.
Abstract Class
Now, we will see here how we can solve our problem using Abstract Class.
1. Define an abstract class as Car.
2. Put all the common functionality in simple methods and all the methods whose implementation is different but name is same. Make them Abstract method.
Here is my Car abstract class.
- using System;
- using System.Collections;
- using System.Collections.Generic;
-
- namespace oops1
- {
- public abstract class Cars
- {
-
-
- public abstract double price();
- public abstract int getTotalSeat();
- public abstract string colors();
-
-
- public string Wheel()
- {
- return "4 wheeler";
-
- }
- public string CheckAC()
- {
- return "AC is available";
- }
- public string CallFacility()
- {
- return "Call Facility supported";
- }
- }
- }
Now, here is my Toyota class which is derived from Cars abstract class.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
-
- namespace oops1
- {
- public class Toyota : Cars
- {
- public string DiscountPrice()
- {
- return "20% discount on buying Toyoya Cars";
- }
- public override double price()
- {
- return 1000000.00;
- }
- public override int getTotalSeat()
- {
- return 5;
- }
- public override string colors()
- {
- return "Red";
- }
-
- static void Main(string[] args)
- {
- Toyota Toy = new Toyota();
- Console.WriteLine("-------Common property defined commonly in Cars Class----------");
-
- Console.WriteLine(Toy.CallFacility());
- Console.WriteLine(Toy.Wheel());
- Console.WriteLine(Toy.CheckAC());
- Console.WriteLine("-------Own property defined in Toyota class------------");
- Console.WriteLine(Toy.DiscountPrice());
- Console.WriteLine("-------Common method but implementation is diffrent defined in IExtra Interface------------");
- Console.WriteLine("Total ONRoad Price:"+ Toy.price());
- Console.WriteLine(Toy.getTotalSeat());
- Console.WriteLine(Toy.colors());
-
- Console.ReadLine();
-
-
- }
- }
-
-
- }
And thus, the result will be the same.
Conclusion
When we have the requirement of a class that contains some common properties or methods with some common properties whose implementation is different for different classes, in that situation, it's better to use Abstract Class then Interface.
Abstract classes provide you the flexibility to have certain concrete methods and some other methods that the derived classes should implement. On the other hand, if you use interfaces, you would need to implement all the methods in the class that extends the interface. An abstract class is a good choice if you have plans for future expansion.
Now, I will explain the second use of Abstract Class here.
Imagine, we have taken a normal parent class as Cars where we have only defined the common methods. And, my Toyota class is derived from the Cars class. This will look like the below code.
- public class Cars
- {
-
- public string Wheel()
- {
- return "4 wheeler";
-
- }
- public string CheckAC()
- {
- return "AC is available";
- }
- public string CallFacility()
- {
- return "Call Facility supported";
- }
-
- }
And, here is the Toyota class after inheriting from Cars.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
-
- namespace oops1
- {
- public class Toyota : Cars
- {
- public string DiscountPrice()
- {
- return "20% discount on buying Toyoya Cars";
- }
-
-
- static void Main(string[] args)
- {
-
-
- Console.ReadLine();
-
-
- }
- }
-
-
- }
Here, users know only the Toyota class, its methods, and properties. The user can access the Cars class property and method by creating the object of Toyota class because it is a child class.
Now, the main demerit of this kind of Implementation is that it allows the user to create the object of the Parent class (which the user should not be aware of and this is not his strategy). Let's see what happens when the user creates the object.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
-
- namespace oops1
- {
- public class Toyota : Cars
- {
- public string DiscountPrice()
- {
- return "20% discount on buying Toyoya Cars";
- }
-
-
- static void Main(string[] args)
- {
-
- Cars ca = new Cars();
- Console.WriteLine("-------Common property defined commonly in Cars Class----------");
-
- Console.WriteLine(ca.CallFacility());
- Console.WriteLine(ca.Wheel());
- Console.WriteLine(ca.CheckAC());
-
- Console.WriteLine("-------Own property defined in Toyota class------------");
- Console.WriteLine(ca.DiscountPrice());
-
-
- Console.ReadLine();
-
-
- }
- }
-
-
- }
As we know, we won't be able to access the child class methods using parent class object, this Cars object will not access the
DiscountPrice() Method because it is a child class method. This implementation will not satisfy our requirement. So, even if the user will create an object of Parent class, we need to check them because using that object, he can't able to access the child class method.