0% found this document useful (0 votes)
19 views

C#Unit-2 Notes

This document discusses classes, objects, and object-oriented programming concepts in C#. It defines a class as a blueprint that combines data and functions, while an object is an instance of a class created at runtime. It explains key OOP concepts like abstraction, encapsulation, inheritance, and polymorphism. It provides examples of creating classes and objects in C#, and using constructors and destructors.

Uploaded by

giridhar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
19 views

C#Unit-2 Notes

This document discusses classes, objects, and object-oriented programming concepts in C#. It defines a class as a blueprint that combines data and functions, while an object is an instance of a class created at runtime. It explains key OOP concepts like abstraction, encapsulation, inheritance, and polymorphism. It provides examples of creating classes and objects in C#, and using constructors and destructors.

Uploaded by

giridhar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 50

Module 2

Classes, Objects and Object-oriented Programming.


Class:
A class is a data structure in C# that combines data variables and
functions into a single unit. Instances of the class are known as objects.
While a class is just a blueprint, the object is an actual instantiation of
the class and contains data. The different operations are performed on
the object.
Object:
An object is a dynamically created instance of the class. It is created at
runtime so it can also be called a runtime entity. All the members of the
class can be accessed using the object of the class.
OOP stands for Object-Oriented Programming.
Procedural programming is about writing procedures or methods that
perform operations on the data, while object-oriented programming is
about creating objects that contain both data and methods.
Object-oriented programming has several advantages over procedural
programming:
 OOP is faster and easier to execute
 OOP provides a clear structure for the programs
 OOP helps to keep the C# code DRY "Don't Repeat Yourself", and
makes the code easier to maintain, modify and debug
 OOP makes it possible to create full reusable applications with less
code and shorter development time.

OOPs Concepts
The key concepts of OOPs are
 Abstraction
 Encapsulation
 Inheritance
 Polymorphism
Abstration:
Abstraction is a concept in OOPS in which only essential details will be
represented and background details will be hidden.
Encapsulation:
Encapsulation is a concept in OOPs wrapping up of data and its
associated functions into a single unit called class.

Inheritance:
Inheritance is a property of OOPs in which a class can inherit the
property of another class. The class which inherits the property of
another class is derived class. The class whose properties are inherited
by derived class is base class.

Polymorphism:
Polymorphism is a concept in OOPs which means one name and
multiple forms.
There are two types of polymorphism in C#:
 Static / Compile Time Polymorphism
 Dynamic / Runtime Polymorphism

Method Overloading/ Static/Compile Time Polymorphism:


 Method overloading is an example of Static polymorphism.

 Overloading is the concept in which method names are the same with
different parameters.

 The method/function has the same name but different signatures in


overloading. It is also known as Early binding.

 It is also known as Compile Time Polymorphism because the decision


of which method is to be called is made at compile time.

Dynamic / Runtime Polymorphism


Dynamic/runtime polymorphism is also known as late binding. Here,
the method name and the method signature (the number of parameters
and parameter type must be the same and may have a different
implementation). Method overriding is an example of dynamic
polymorphism.
Method overriding can be done using inheritance. With method
overriding, it is possible for the base class and derived class to have the
same method name and the same something. The compiler would not be
aware of the method available for overriding the functionality, so the
compiler does not throw an error at compile time. The compiler will
decide which way to call at runtime, and if no method is found, it throws
an error.

Method Overriding in C#
If the same method is present in both the base class and the derived
class, the method in the derived class overrides the method in the base
class. This is called method overriding in C#.

Creating a class:
To create a class, use the class keyword:
using System;
class Dog {
//field
string breed;
//method
public void bark(){
Console.WriteLine("Bow Bow!!")
}
}

Here, we have created a class named Dog. A class can contain


fields - variables to store data. In our example breed is the field or
member data.
methods - functions to perform specific tasks.
In our example bark is the function/method. When called will print
“Bow Bow!!”.

Creating an object:
An object is an instance of a class. Suppose, we have a class Dog. Bulldog,
German Shepherd, Pug are objects of the class.
Syntax for creating an object:
ClassName obj = new ClassName();
Example:
Dog bullDog = new Dog();
Now, the bullDog object can access the fields and methods of the Dog
class.

Example to Demonstrate Accessing the member data and


member functions of a class using the object of the class.
We use the name of objects along with the . operator to access members
of a class. For example,
using System;
namespace ClassObject {
class Dog {
string breed;

public void bark() {


Console.WriteLine("Bark Bark !!");
}

static void Main(string[] args) {


// create Dog object
Dog bullDog = new Dog();

// access breed of the Dog


bullDog.breed = "Bull Dog";
Console.WriteLine(bullDog.breed);

// access method of the Dog


bullDog.();

//Console.ReadKey();
}
}
}

Output
Bull Dog
Bark Bark !!
C# this Keyword
In C#, this keyword refers to the current instance of a class. For example,
using System;

namespace ThisKeyword {
class Test {

int num;
Test(int num) {
// this.num refers to the instance field
this.num = num;
Console.WriteLine("object of this: " + this);
}

static void Main(string[] args) {

Test t1 = new Test(4);


Console.WriteLine("object of t1: " + t1);
Console.ReadLine();
}
}
}

Output
object of this: ThisKeyword.Test
object of t1: ThisKeyword.Test

In the above example, we have created an object named t1 of the class


Test. We have printed the name of the object t1 and this keyword of the
class.
Here, we can see the name of both t1 and this is the same. This is because
this keyword refers to the current instance of the class which is t1.

Note:
The reference variable "this" is allocated within the method stack
whenever a non-static method or constructor is called. It means the
"this" reference variable can be allocated several times to hold the
address of a single object.
The reference variable "this" is automatically initialized with the
reference of the current object for which the non-static method or
constructor is called.

Constructors and Destructors:


Category Constructor Destructor
What is the use of Destructors are used to clean
Constructors are used when
Constructors & up resources used by the
instantiating a class.
Destructors? object.
Destructor is opposite of
The constructor is a special
What are constructor. It is a special
method of the class that is
Constructors & method of the class that is
called when a class is
Destructors? invoked when a class object
instantiated.
goes out of scope.
Destructor name is same as
Name of Constructor
E class name with starting ~.
& Destructor?
~<ClassName>
Constructor can have access
Destructor can’t have access
Access Modifiers? modifiers.
modifiers.
By default it is public.
Parameterized
Constructor can have Destructor can’t have
Constructor and
parameter(s). parameter(s).
Destructor?
Constructors can be divided into
5 types:
Default Constructor (Parameter
Types of Constructor Destructor can’t have different
Less Constructor),
and Destructor? types.
Parameterized Constructor,
Copy Constructor, Static
Constructor, Private Constructor
Destructors can’t be multiple in
Number of
Constructors can be multiple in a class.
Constructors and
a class. A Destructor is unique to its
Destructors?
class.
Constructors and
Constructors can be defined in Destructors can’t be defined in
Destructors defined
Structures. Structures.
in Structures?
When are Destructors are invoked
Constructor gets automatically
Constructors and automatically, and cannot be
invoked whenever an instance
Destructors invoked explicitly.
of the class is created.
invoked? Execution of the destructor for
the instance may occur at any
time after the instance
becomes eligible for
destruction.

Example Program to demonstrate the use of constructors and destructors.

class Member
{
public Member(){
Console.WriteLine("Default Constructor was called.");
}

public Member(string name){


Console.WriteLine("Parameterized Constructor was called.");
}

~Member(){
Console.WriteLine("Destructor was called.");
}
}
class Program{
static void Main(string[] args){
Member member1 = new Member();

Member member2 = new Member("Rahul");


Console.ReadKey();
}
}

Creating an array of Objects:


An array of object is similar as any other primitive data type.
using System;
class Car
{
//Member data declaration.
public string color;

public Car(string c)
{
color=c;
}
static void main(string[] args)
{
//Creating object array.
Car[] obj = new Car[3];

//Initializing objects
obj[0]=new Car("Cian");
obj[1]=new Car("Dodger Blue");

//Printing Data of Object 1


Console.WriteLine(obj[0].color);

//Printing Data of Object 2


Console.WriteLine(obj[1].color);
}
}

C# Nested classes:
In C#, we can define a class within another class. It is known as a nested
class. For example,
class OuterClass {
//Body of the outer class.
class InnerClass {
//Body of the inner class.
}
}
Here, we have created the class InnerClass inside the class OuterClass.
The InnerClass is called the nested class.
Access Members
To access members of the nested classes we first need to create their
objects.

1.Create object of Outer class


OuterClass obj1 = new OuterClass();
Here, we have created the obj1 object of the class OuterClass.

2. Create object of Inner Class


OuterClass.InnerClass obj2 = new OuterClass.InnerClass();
You can see that we have used OuterClass.InnerClass to create the obj2
object of the inner class. This is because InnerClass is the nested class of
OuterClass.

Once we have created the object of individual classes, we can use the
object name and dot operator to access members of each class.

Example: C# Nested Class


using System;
namespace CsharpNestedClass {

// outer class
public class Car {

public void displayCar() {


Console.WriteLine("Car: Bugatti");
}

// inner class
public class Engine {
public void displayEngine() {
Console.WriteLine("Engine: Petrol Engine");
}
}
}
class Program {
static void Main(string[] args) {

// create object of outer class


Car sportsCar = new Car();
// access method of outer class
sportsCar.displayCar();

// create object of inner class


Car.Engine petrolEngine = new Car.Engine();

// access member of inner class


petrolEngine.displayEngine();

Console.ReadLine();

}
}
}

In the above program, we have nested the Engine class inside the Car
class.

Inside the Program class, we have created objects of both the outer class
and the inner class.

We then used these objects to access methods of each class.

sportsCar.displayCar() - access outer class method using the object of


Car
petrolEngine.displayEngine() - access inner class method using the
object of Engine

Note: We cannot access the members of the inner class using the object
of the outer class.

For example,
// error code
sportsCar.displayEngine();
Here, we cannot access the displayEngine() method of the inner class
Engine using the sportsCar object of the outer class.
We can access members of the outer class inside the inner class. For this
we use an object of the outer class.
If we need to access static members of the outer class, we don't need to
create its object. Instead, we can directly use the name of the outer class.

Notice that we have used the name of the outer class along with the
nested class to inherit the inner class.
class Laptop : Computer.CPU {}

Partial classes:
While programming in C# (or OOP), we can split the definition of a class
over two or more source files. The source files contains a section of the
definition of class, and all parts are combined when the application is
compiled. For splitting a class definition, we need to use the partial
keyword.
The partial keyword specify that other parts of the class can be defined in
the namespace. It is mandatory to use the partial keyword if we are
trying to make a class partial. All the parts of the class should be in the
same namespace and available at compile time to form the final type. All
the parts must have same access modifier i.e. private, public, or so on.
If any part is declared abstract, then the whole type is considered
abstract.
If any part is declared sealed, then the whole type is considered sealed.
If any part declares a base type, then the whole type inherits that class.
Any class member declared in a partial definition are available to all
other parts.
All parts of a partial class should be in the same namespace.
**Note: The partial modifier is not available on delegate or enumeration
declarations

Example demonstrating partial classes:


We have a project named as HeightWeightInfo which shows height and
weight.
We have a file named as File1.cs with a partial class named as Record. It
has two integer variables h & w and a method/constructor named as
Record which is assigning the values of h & w.
namespace HeightWeightInfo
{
class File1
{
}
public partial class Record
{
private int h;
private int w;
public Record(int h, int w)
{
this.h = h;
this.w = w;
}
}
}
Here is another file named as File2.cs with the same partial class Record
which has only the method PrintRecord. This method will display the
values of h & w.

namespace HeightWeightInfo
{
class File2
{
}
public partial class Record
{
public void PrintRecord()
{
Console.WriteLine("Height:"+ h);
Console.WriteLine("Weight:"+ w);
}
}
}
Here now we can see the main method of the project:

namespace HeightWeightInfo
{
class Program
{
static void Main(string[] args)
{
Record myRecord = new Record(10, 15);
myRecord.PrintRecord();
Console.ReadLine();
}
}
}
Here we have the object of the class Record as myRecord which is
passing the parameter values as 10 and 15 to h and w respectively to the
method defined in File1.cs.

The method PrintRecord is called by the object myRecord which is


defined in the File2.cs.

This shows that the partial keyword helps to combine all the attributes of
a class defined in various files to work as a single class.

Places where partial class can be used:


While working on a larger projects with more than one developer, it
helps the developers to work on the same class simultaneously.
Codes can be added or modified to the class without re-creating source
files which are automatically generated by the IDE (i.e. Visual Studio).
Partial Method:
Let's take an example as a partial class Car defined in file1.cs which has
three methods InitializeCar(), BuildRim() and BuildWheels(). Among
those methods, InitializeCar is defined as partial.

public partial class Car


{
partial void InitializeCar();
public void BuildRim() { }
public void BuildWheels() { }
}
And we have another file named as file2.cs which has two methods
BuildEngine and InitializeCar. The method InitializeCar is partial
method which is also defined in file1.cs.

public partial class Car


{
public void BuildEngine() { }
partial void InitializeCar()
{
string str = "Car";
}
}
A partial method declaration consists of two parts:

The definition as in file1.cs.


The implementation as in file2.cs.
They may be in separate parts of the partial class, or in the same part.

Things to remember about Partial Method


partial keyword.
return type void.
implicitly private.
and cannot be virtual.

Returning value from a method.


C# access Modifiers
Access Modifiers ( Access Specifiers ) describes as the scope of
accessibility of an Object and its members.
In C#, access modifiers specify the accessibility of types (classes,
interfaces, etc) and type members (fields, methods, etc).
For example,
class Student {
public string name;
private int num;
}

Here,
name - public field that can be accessed from anywhere
num - private field can only be accessed within the Student class

Types of Access Modifiers

In C#, there are 4 basic types of access modifiers.


1. public
2. private
3. protected
4. internal
1. public access modifier
When we declare a type or type member public, it can be accessed from
anywhere using the object of that class. The scope of the accessibility is
inside class as well as outside.

2. private access modifier


When we declare a type member with the private access modifier, it can
only be accessed within the same class or struct.
The private members cannot be accessed outside the class and it is the
least permissive access level .

3. protected access modifier


When we declare a type member as protected, it can only be accessed
from the same class and its derived classes.
The scope of accessibility is limited within the class or struct and the
class derived (Inherited )from this class.

4. internal access modifier


When we declare a type or type member as internal, it can be accessed
only within the same assembly. The internal access modifiers can access
within the program that contain its declarations and also access only
within files in the same assembly level but not from another assembly.

An assembly is a collection of types (classes, interfaces, etc) and


resources (data). They are built to work together and form a logical unit
of functionality.

That's why when we run an assembly all classes and interfaces inside the
assembly run together.

5. Protected Internal Access Modifier


Protected internal is the same access levels of both protected and
internal . It can access anywhere in the same assembly also be accessed
within a derived class in another assembly.

6. private protected access modifier


The private protected access modifier is a combination of private and
protected. It is available from the C# version 7.2 and later.

When we declare a member private protected, it can only be accessed


within the same class, and its derived class within the same assembly.

C# static keyword:
In C#, if we use a static keyword with class members, then there will be a
single copy of the type member.
And, all objects of the class share a single copy instead of creating
individual copies.

C# Static Variables
If a variable is declared static, we can access the variable using the class
name. For example,
Suppose if we declare a static variable name in student class,
// static variable
public static string name = "Kamal Hassan";

// access static variable


Console.WriteLine("Hello Mr. : " + student.name);

In the above example, we have created a static variable named name.


Since the variable is static, we have used the class name student to access
the variable.

C# Static Methods
Just like static variables, we can call the static methods using the class
name.

using System;
class Test {
public static void display() {
Console.WriteLine(“Hello”);
}
}

class Program {
static void Main(string[] args) {
Test.display();
}
}

In the above example display is the static method. Only a single copy of
this method is accessible by all objects of class.
As it belongs to the class Test. Test.display() method is used to access the
method.

In C#, a static class is a class that cannot be instantiated.


The main purpose of using static classes in C# is to provide blueprints of
its inherited classes.
A static class is created using the static keyword in C# and .NET.
A static class can contain static members only.
You can‘t create an object for the static class.

Advantages of Static Classes


 You will get an error if you declare any member as a non-static
member.
 When you try to create an instance to the static class, it again
generates a compile time error because the static members can be
accessed directly with their class name.
 The static keyword is used before the class keyword in a class
definition to declare a static class.
 Static class members are accessed by the class name followed by the
member name.

//Syntax of Static class


static class classname
{
//static data members
//static methods
}
C# Static Class Example:
using System;

namespace StaticKeyword {

static class Test {


static int a = 5;
static void display() {
Console.WriteLine("Static method");
}

static void Main(string[] args) {

// creating object of Test


Test t1 = new Test();
Console.WriteLine(a);
display();
}
}
}
n the above example, we have a static class Test. We have created an
object t1 of the class Test.

Since we cannot make an object of the static class, we get the following
error:
error CS0723: Cannot declare a variable of static type 'Test'
error CS0712: Cannot create an instance of the static class
Notice the field and method of the static class are also static because we
can only have static members inside the static class.
Access static Members within the Class
If we are accessing the static variables and methods inside the same
class, we can directly access them without using the class name. For
example,

using System;
namespace StaticKeyword {

class Test {
static int age = 25;
public static void display() {
Console.WriteLine("Static method");
}
static void Main(string[] args) {
Console.WriteLine(age);
display();
Console.ReadLine();
}
}
}
Output
25
Static method

Here, we are accessing the static field age and static method display()
without using the class name.
1. Readonly Fields:
 In C#, you are allowed to declare a field using readonly modifier.
 It indicates that the assignment to the fields is only the part of the
declaration or in a constructor to the same class.
 Such types of fields can only be assigned or reassigned multiple times
only at the declaration or in a constructor.
 They are not assigned after the constructor exit. If the readonly
modifier is used with a value type field, then the field is immutable.
 And if the readonly modifier is used with a reference type field, then
the readonly modifier prevents the field from replaced by the different
instances of the reference type, here the readonly modifier does not
stop the instance data of the field from being modified through the
read-only field.
 In static and instance constructors, you are allowed to pass a readonly
field as an out or ref parameter.
// how to create a readonly field
using System;

class example {

// readonly variables
public readonly string str1;
public readonly string str2;

// Readonly variable
// This variable is
// initialized at declaration time
public readonly string str3 = "VcetMCA";

// The values of the readonly


// variables are assigned
// Using constructor
public example(string a, string b)
{

str1 = a;
str2 = b;
Console.WriteLine("Display value of string 1 {0}, "
+ "and string 2 {1}", str1, str2);
}

// Main method
static public void Main()
{
example ob = new example("VCET", "MCA");
}
}
Display value of string 1 VCET, and string 2 MCA

Static Readonly
A Static Readonly type variable's value can be assigned at runtime or
assigned at compile time and changed at runtime. But this variable's
value can only be changed in the static constructor. And cannot be
changed further. So it can change only once at runtime.
C# Indexers
An indexer allows us to access instances of a class using an index just like
an array.

Example: C# indexer
using System;
class Program
{
// declare an array to store elements
private string[] studentName = new string[10];

// define an indexer
public string this[int index]
{
get
{
// return value of stored at studentName array
return studentName[index];
}

set
{
// assigns value to studentName
studentName[index] = value;
}
}

public static void Main()


{
// create instance of Program class
Program obj = new Program();

// insert values in obj[] using indexer i.e index position


obj[0] = "Harry";
obj[1] = "Ron";
obj[2] = "Hermoine";

Console.WriteLine("First element in obj: " + obj[0]);


Console.WriteLine("Second element in obj: " + obj[1]);
}
}
Output

First element in obj: Harry


Second element in obj: Ron

In the above example, notice the code

// declare an array to store elements


private string[] studentName = new string[10];
Here, we have declared the studentName array of size 10.

Then we have defined an indexer of string type.

Here, the set method assigns values to studentName using index. And
the get method returns values stored at studentName.
Here, we have used obj (instance of the Program class) like the
studentName array.
Note: Without using indexer, we access the studentName array through
obj as:
// insert value to studentName array when indexer is not used
obj.studentName[0] = "Harry";
Indexer helps to simplify the syntax.
C# Structures:
The struct (structure) is like a class in C# that is used to store data.
However, unlike classes, a struct is a value type.
Suppose we want to store the name and age of a person. We can create
two variables: name and age and store value.
In this case, creating variables for an individual person might be a
tedious task. To overcome this we can create a struct that stores name
and age. Now, this struct can be used for every person.
Define struct in C#
In C#, we use the struct keyword to define a struct.
For example,

struct Employee {
public int id;
public string name;
public double salary;
}

Here, id, name and salary are fields inside the struct. A struct can include
methods, indexers, etc as well.
Declare struct variable
Before we use a struct, we first need to create a struct variable. We use a
struct name with a variable to declare a struct variable. For example,
// declare emp of struct Employee
Employee emp;

In the above example, we have created a struct named Employee. Here,


we have declared a variable emp of the struct Employee.

Access C# struct
We use the struct variable along with the . operator to access members of
a struct. For example,
// access member of struct
emp.id = 1;
emp.name = “John Cena”;
emp.salary = 25000.213;
Here, we have used variable emp of a struct Employee with . operator to
access members of the Employee.
Note: We can also instantiate a struct using the new keyword. For
example,
Employee emp = new Employee();

Constructors in C# struct
In C#, a struct can also include constructors. For example,
struct Employee {

public int id;


// constructor
public Employee(int employeeId) {
id = employeeId
}
}
Here, we have created a parameterized constructor Employee() with
parameter employeeId.

Note: We cannot create parameterless constructors in C# version 9.0 or


below.

System.objectClass
 All .NET classes are ultimately derived from the System.Object class.
 In fact, when you don’t specify a base class while defining a class, the
compiler automatically assumes that it derives from System.Object.
 Lastly, because of this behavior, you have access to many public,
protected member methods that have been defined for the Object
class.
 System.Object is the parent of all classes within the .NET.
 All class builtin and/or defined is a subclass of System.Object
 The Object class is the base class for all the classes in the .Net
Framework.
 It is present in the System namespace.
 In C#, the .NET Base Class Library(BCL) has a language-specific alias
which is Object class with the fully qualified name as System.Object.
 Every class in C# is directly or indirectly derived from the Object
class. If a class does not extend any other class then it is the direct
child class of the Object class and if extends another class then it is
indirectly derived.
 Therefore the Object class methods are available to all C# classes.
Hence Object class acts as a root of the inheritance hierarchy in any
C# Program.
 The main purpose of the Object class is to provide low-level services
to derived classes.

Encapsulation in C#
Encapsulation allows an object to control access to its data and methods,
which can improve the security and stability of the system.

In OOP, encapsulation is typically achieved through the use of access


modifiers, such as "private" and "protected," which restrict access to
certain members of a class.

Encapsulation is an important concept in object-oriented programming


(OOP) because it allows you to hide the internal details
(implementation) of an object from other objects and the outside world.
In C#, encapsulation is achieved through the use of access modifiers,
such as "private," "protected," and "internal."
"private" members of a class can only be accessed within the class itself.
"protected" members can be accessed within the class and any derived
classes.
"internal" members can be accessed within the same assembly.
By default, members of a class are private.

Encapsulation using Accessors and mutators


Accessors and mutators are methods that are used to get and set the
values of a variable.
using System;
namespace Employee {
public class EmployeeDetail {
private string Name;
//Accessor
public string get() {
return Name;
}

//Mutators
public string set(string name) {
Name = name;
}
}
public class MainClass {
public static void Main(string[] args) {
EmployeeDetail detail = new EmployeeDetail();
detail.set("Ghost");
Console.WriteLine("The Employee Name is :" + detail.get());
Console.ReadLine();
}
}
}

Output:
The Employee Name is :Ghost

We have defined two methods set and get. The set method, mutator, sets
the value of the Name variable. The get method, accessor, displays the
value of the Name variable on the screen.
C# Inheritance:
In C#, it is possible to inherit fields and methods from one class to
another. We group the "inheritance concept" into two categories:

Derived Class (child) - the class that inherits from another class
Base Class (parent) - the class being inherited from
To inherit from a class, use the : symbol.

In the example below, the Car class (child) inherits the fields and
methods from the Vehicle class (parent):

Inheritance allows us to create a new class from an existing class. It is a


key feature of Object-Oriented Programming (OOP).
The class from which a new class is created is known as the base class
(parent or superclass). And, the new class is called derived class (child or
subclass)
The derived class inherits the fields and methods of the base class. This
helps with the code reusability in C#.
How to perform inheritance in C#?
In C#, we use the : symbol to perform inheritance. For example,

class Animal {
// fields and methods
}

// Dog inherits from Animal


class Dog : Animal {
// fields and methods of Animal
// fields and methods of Dog
}

Here, we are inheriting the derived class Dog from the base class Animal.
The Dog class can now access the fields and methods of Animal class.
Note:
protected Members in C# Inheritance
When we declare a field or method as protected, it can only be accessed
from the same class and its derived classes.

Different types of Inheritance:


There are the following types of inheritance:
1. Single Inheritance
In single inheritance, a single derived class inherits from a single base
class.
Syntax:
AccessSpecifier derieved_class : base_class
{Body of derieved class}
2. Multilevel Inheritance
In multilevel inheritance, a derived class inherits from a base and then
the same derived class acts as a base class for another class.
Syntax:
AccessSpecifier derievedClass : PreviouslyDerievedClass
{Body of derieved class}

3. Hierarchical Inheritance
In hierarchical inheritance, multiple derived classes inherit from a single
base class.
Syntax:
AccessSpecifier derieved_class1 : base_class
{Body of derieved class}
AccessSpecifier derieved_class2 : base_class
{Body of derieved class}
4. Multiple Inheritance
In multiple inheritance, a single derived class inherits from multiple base
classes. C# doesn't support multiple inheritance. However, we can
achieve multiple inheritance through interfaces.

5. Hybrid Inheritance
Hybrid inheritance is a combination of two or more types of inheritance.
The combination of multilevel and hierarchical inheritance is an example
of Hybrid inheritance.

Constructors and Inheritance in C#:


If you provide the constructor in the derived class, you must provide an
appropriate constructor in the base class. If you have provided a
constructor in the derived class and no constructor in the base class, the
compiler will flag an error.

Now, suppose I have a constructor in the derived/subclass class and in


the base class as well, remember that the base class constructor will be
called first and then derived class constructor. If I create the instance of
the derived class, let us see this behavior with an example.

Example:
class Base
{
public Base() {
Console.WriteLine("Inside Base Constructor");
}
~Base() {
Console.WriteLine("Inside Base Destructor");
}
}
class Derived: Base {
public Derived() {
Console.WriteLine("Inside The Derived Constructor");
}
~Derived() {
Console.WriteLine("Inside The Derived Destructor");
}
}

The derived class is getting inherited from the base class. Both the
classes have a default constructor, where I am printing appropriate
messages.

Now, if I create an instance of a derived class as


Derived obj=new Derived();

The output of my program will be:


Inside Base class constructor
Inside Derived class constructor

The important point to note from this output is that the base class
constructor is being called first and then derived class constructor.

Default constructor of base class is called automatically from derived


class.

Now, to manually call the constructor of the base class from the derived
class constructor. We need to do this, using base keyword.

Let us see the example.

Suppose, I have two classes, given below:


class Class1
{
protected int a, b;
public Class1() {
a = 0;
b = 0;
Console.WriteLine("Inside base class default constructor");
}
public Class1(int a, int b) {
this.a = a;
this.b = b;
Console.WriteLine("Inside base class parameterized constructor");
}
}
class Class2: Class1 {
int c;
public Class2(int a, int b, int c): base(a, b) {
this.c = c;
Console.WriteLine("Inside derived class parametrized constructor");
}
}

Observe the line public Class2(int a, int b, int c) : base(a, b)


Now, here I am calling the base class constructor, using base(a, b)
Now, when I create the instance of the derived class as
Class2 obj2 = new Class2(2, 3, 4);

Thus, the base class constructor, that takes two parameters is called first
and then the derived class constructor. Output of this is:
Inside Baseclass parameterized constructor.
Inside Derivedclass parameterized constructor.

in inheritance from the derived class constructor, the base class


constructor will be called either automatically or manually (using base
keyword)
If we create a constructor in the derived class, no constructor in the base
class compiler will flag an error. Thus, when you create a constructor in
the derived class, you must create a constructor in the base class as well.

Sealed Classes in C#
A sealed class, in C#, is a class that cannot be inherited by any class but
can be instantiated.

In C#, when we don't want a class to be inherited by another class, we


can declare the class as a sealed class.
A sealed class cannot have a derived class. We use the sealed keyword to
create a sealed class. For example,
using System;
namespace SealedClass {
sealed class baseclass {

// trying to inherit sealed class


class derievedclass : baseclass {

class Program {
static void Main (string [] args) {

// create an object of Dog class


derievedclass d1 = new derievedclass();
Console.ReadLine();
}
}
}

In the above example, we have created a sealed class baseclass. Here, we


are trying to derive derievedclass class from the baseclass class.

Since a sealed class cannot be inherited, the program generates the


following error:
error CS0509: 'derievedclass': cannot derive from sealed type 'baseclass'.

Sealed method:
During method overriding, if we don't want an overridden method to be
further overridden by another class, we can declare it as a sealed
method.

We use a sealed keyword with an overridden method to create a sealed


method. For example,
namespace SealedDemo
{
class Parent
{
public virtual void Show() { }
}
class Child : Parent
{
public sealed override void Show() { }
}
class GrandChild : Child
{
//'GrandChild.Show()': cannot override inherited member
'Child.Show()' because it is sealed
public override void Show() { }
}
}

error CS0239: GrandChild.Show()': cannot override inherited member


Child.Show()' because it is sealed

Note: Sealing an overridden method prevents method overriding in


multilevel inheritance.
Extension methods:
Extension methods, as the name suggests, are additional methods.
Extension methods allow you to inject additional methods without
modifying, deriving or recompiling the original class, struct or interface.
Extension methods can be added to your own custom class, .NET
framework classes, or third party classes or interfaces.
In the following example, IsGreaterThan() is an extension method for int
type, which returns true if the value of the int variable is greater than the
supplied integer parameter.

Example: Extension Method


int i = 10;
bool result = i.IsGreaterThan(100); //returns false

The IsGreaterThan() method is not a method of int data type (Int32


struct). It is an extension method written by the programmer for the int
data type. The IsGreaterThan() extension method will be available
throughout the application by including the namespace in which it has
been defined.
The extension methods have a special symbol in intellisense of the visual
studio, so that you can easily differentiate between class methods and
extension methods.
An extension method is actually a special kind of static method defined
in a static class. To define an extension method, first of all, define a static
class.
For example, we have created an IntExtensions class under the
ExtensionMethods namespace in the following example. The
IntExtensions class will contain all the extension methods applicable to
int data type. (You may use any name for namespace and class.)
Polymorphism:
Function Overloading or compile time polymorphism
using System;
namespace MethodOverload {
class Program {

// method with one parameter


void display(int a) {
Console.WriteLine("Arguments: " + a);
}
// method with two parameters
void display(int a, int b) {
Console.WriteLine("Arguments: " + a + " and " + b);
}
static void Main(string[] args) {
Program p1 = new Program();
p1.display(100);
p1.display(100, 200);
Console.ReadLine();
}
}
}
Output:
Arguments: 100
Arguments: 100 and 200

In the above example, we have overloaded the display() method:


one method has one parameter
another has two parameters
Based on the number of the argument passed during the method call, the
corresponding method is called.

p1.display(100) - calls the method with single parameter


p1.display(100, 200) - calls the method with two parameters

Run Time Polymorphism or Function Overriding.


For example,
class base_class
{
public void display()
{
Console.WriteLine(“Displaying in base class”);
}
}

class derived_class : base_class


{
public void display()
{
Console.WriteLine(“Displaying in derieved class”);
}
}

class Main_Method
{
static void Main()
{
derived_class d = new derived_class();
d.display();
}
}
In the above example the display() function from the derived class
overrides the display() function in the base_class.

Abstract Class
In C#, we cannot create objects of an abstract class. We use the abstract
keyword to create an abstract class. For example,

using System;
namespace abstractclass{
// create an abstract class
abstract class absclass {
// fields and methods
}
// try to create an object Language
class abs{
public static void Main (string [] args) {

absclass obj = new absclass();


}
// throws an error
}
}
// throws an error
cs(14,16): error CS0144: Cannot create an instance of the abstract type or
interface 'absclass'

An abstract class can have both abstract methods (method without body)
and non-abstract methods (method with the body). For example,
abstract class Language {
// abstract method
public abstract void display1();

// non-abstract method
public void display2() {
Console.WriteLine("Non abstract method");
}
}

Inheriting Abstract Class


As we cannot create objects of an abstract class, we must create a derived
class from it. So that we can access members of the abstract class using
the object of the derived class. For example,

using System;
namespace AbstractClass {
abstract class absclass {
// non-abstract method
public void display() {
Console.WriteLine("Non abstract method");
}
}

// inheriting from abstract class


class derivedclass : absclass {

static void Main (string [] args) {

// object of Program class


derivedclass obj = new derivedclass();

// access method of an abstract class


obj.display();
Console.ReadLine();
}
}
}

Output:
Non abstract method
In the above example, we have created an abstract class named
Language. The class contains a non-abstract method display().
We have created the Program class that inherits the abstract class.
Notice the statement,

obj.display();
Here, obj is the object of the derived class Program. We are calling the
method of the abstract class using the object obj.
Note: We can use abstract class only as a base class. This is why abstract
classes cannot be sealed.
C# Abstract Method
A method that does not have a body is known as an abstract method. We
use the abstract keyword to create abstract methods.
For example,
public abstract void display();

Here, display() is an abstract method. An abstract method can only be


present inside an abstract class.

When a non-abstract class inherits an abstract class, it should provide an


implementation of the abstract methods.

If an abstract method is not implemented in the derived class the


following error will be thrown.

Example Demonstrating abstract methods.

using System;
namespace AbstractClass {

abstract class Animal {


// abstract method
public abstract void makeSound();
}

// inheriting from abstract class


class Dog : Animal {
// provide implementation of abstract method
public void makeSound() {

Console.WriteLine("Bark Bark");
}
}
class Program {
static void Main (string [] args) {
// create an object of Dog class
Dog obj = new Dog();
obj.makeSound();
Console.ReadLine();
}
}
}
Output:
Bark Bark
In the above example, we have created an abstract class named Animal.
We have an abstract method makeSound() inside the class.

We have a Dog class that inherits from the Animal class. Dog class
provides the implementation of the abstract method makeSound().

error CS0534: 'Dog' does not implement inherited abstract member


'Animal.makeSound()'.

// provide implementation of abstract method


public override void makeSound() {
Console.WriteLine("Bark Bark");
}

Notice, we have used override with the makeSound() method. This


indicates the method is overriding the method from the base class.

We then used the object of the Dog class to access makeSound().

If the Dog class had not provided the implementation of the abstract
method makeSound(), Dog class should have been marked abstract as
well.

Note: Unlike the C# inheritance, we cannot use virtual with the abstract
methods of the base class. This is because an abstract class is implicitly
virtual.

C# interface
In C#, an interface is similar to abstract class. However, unlike abstract
classes, all methods of an interface are fully abstract (method without
body).
We use the interface keyword to create an interface. For example,
interface IPolygon {
// method without body
void calculateArea();
}

Here,

 IPolygon is the name of the interface.


 By convention, interface starts with I so that we can identify it just by
seeing its name.
 We cannot use access modifiers inside an interface.
 All members of an interface are public by default.
 An interface doesn't allow fields.

Implementing an Interface
We cannot create objects of an interface. To use an interface, other
classes must implement it. Same as in C# Inheritance, we use : symbol to
implement an interface.
For example,
using System;
namespace CsharpInterface {

interface IPolygon {
// method without body
void calculateArea(int l, int b);

class Rectangle : IPolygon {


// implementation of methods inside interface
public void calculateArea(int l, int b) {
int area = l * b;
Console.WriteLine("Area of Rectangle: " + area);
}
}

class Program {
static void Main (string [] args) {
Rectangle r1 = new Rectangle();
r1.calculateArea(100, 200);
}
}
}
Output
Area of Rectangle: 20000

In the above example, we have created an interface named IPolygon. The


interface contains a method calculateArea(int a, int b) without
implementation.

Here, the Rectangle class implements IPolygon. And, provides the


implementation of the calculateArea(int a, int b) method.

Note: We must provide the implementation of all the methods of


interface inside the class that implements it.

Inheritance of Interface:
// C# program to illustrate the concept of inheritance in interface

using System;

// declaring an interface
public interface A {

// method of interface
void mymethod1();
void mymethod2();
}

// The methods of interface A is inherited into interface B


public interface B : A {

// method of interface B
void mymethod3();
}
// Below class is inheriting
// only interface B
// This class must
// implement both interfaces
class Inherited : B
{

// implementing the method of interface A


public void mymethod1()
{
Console.WriteLine("Implement method 1");
}

// Implement the method of interface A


public void mymethod2()
{
Console.WriteLine("Implement method 2");
}

// Implement the method of interface B


public void mymethod3()
{
Console.WriteLine("Implement method 3");
}
}

// Driver Class
class Program {

// Main method
static void Main(String []args)
{

// creating the object


// class of Inherited
Inherited obj = new Inherited();

// calling the method


// using object 'obj'
obj.mymethod1();
obj.mymethod2();
obj.mymethod3();
}
}

You might also like