Object-oriented programming (OOP) is a programming language model organized around objects rather than "actions" and data rather than logic. Historically,a program has been viewed as a logical procedure that takes input data, processes it, and produces output data.
1 (oops)
2 (class)
3 (Class & Struct Diff..)
4 (object)
5 (Abstraction)
6 (Encapsulation)
7 (Encaps & Abst Diff..)
8 (Access Specifiers)
9 (specifiers in proper..)
10 (Object And Instance)
11 (pointers in C#)
12 (Inheritance)
13 (Why multi inheri...)
14 (Method Hiding)
15 (Polymorphism)
16 (Cohesion&Coupling)
17 (Coupling..)
18 (Constru & Dest..)
19 (Abst Class&method)
20(Interface)
21(Abst. Class & Int)
22(Use of abst and Int)
23(Static Class & Mem)
24(Aggregation,Asso...)
25(SOLID Principles)
2.Class:
Class is the collection of variables for storing data and functions to specify various operations that can be performed on data. Class does not occupy any memory space and hence it is only logical representation of data.
Example:
System;
System.Collections.Generic;
System.Linq;
System.Text;
oopsCode
{
Program
{
Main(string[] args)
{
Employee Emp =
Employee();
Emp.GetEmployeeSal();
.ReadLine();
}
}
Employee
{
dblEmpsal = 70000;
GetEmployeeSal()
{
.WriteLine("Employee salary
{0}", dblEmpsal);
}
}
}
***********
***********
OUTPUT :
Employee salary
70000
1 (oops)
2 (class)
3 (Class & Struct Diff..)
4 (object)
5 (Abstraction)
6 (Encapsulation)
7 (Encaps & Abst Diff..)
8 (Access Specifiers)
9 (specifiers in proper..)
10 (Object And Instance)
11 (pointers in C#)
12 (Inheritance)
13 (Why multi inheri...)
14 (Method Hiding)
15 (Polymorphism)
16 (Cohesion&Coupling)
17 (Coupling..)
18 (Constru & Dest..)
19 (Abst Class&method)
20(Interface)
21(Abst. Class & Int)
22(Use of abst and Int)
23(Static Class & Mem)
24(Aggregation,Asso...)
25(SOLID Principles)
3.Difference between class and struct:
1.Classes are Reference types and Structures are Values types.
2.Classes will support an Inheritance whereas Structures won’t
3.Classes can have explicitly parameter less constructors whereas structures can’t
4.Member variable initialization is possible in class whereas in Structures, it is not
5.It is not possible to declare destructor in structure but in class it is possible
In general, classes can be used when you have more complex behavior or data. And if you think that these behavior or data to be modified after creating an instance of class, then classes are absolute methods.Structures can be used for small data structures. If developer feels that data members of structure cannot to be modified after creating structure, then having structure will suit
1 (oops)
2 (class)
3 (Class & Struct Diff..)
4 (object)
5 (Abstraction)
6 (Encapsulation)
7 (Encaps & Abst Diff..)
8 (Access Specifiers)
9 (specifiers in proper..)
10 (Object And Instance)
11 (pointers in C#)
12 (Inheritance)
13 (Why multi inheri...)
14 (Method Hiding)
15 (Polymorphism)
16 (Cohesion&Coupling)
17 (Coupling..)
18 (Constru & Dest..)
19 (Abst Class&method)
20(Interface)
21(Abst. Class & Int)
22(Use of abst and Int)
23(Static Class & Mem)
24(Aggregation,Asso...)
25(SOLID Principles)
4.Object:
It is a real time entity. It is an instance of a class
Example:
emp = ();
1 (oops)
2 (class)
3 (Class & Struct Diff..)
4 (object)
5 (Abstraction)
6 (Encapsulation)
7 (Encaps & Abst Diff..)
8 (Access Specifiers)
9 (specifiers in proper..)
10 (Object And Instance)
11 (pointers in C#)
12 (Inheritance)
13 (Why multi inheri...)
14 (Method Hiding)
15 (Polymorphism)
16 (Cohesion&Coupling)
17 (Coupling..)
18 (Constru & Dest..)
19 (Abst Class&method)
20(Interface)
21(Abst. Class & Int)
22(Use of abst and Int)
23(Static Class & Mem)
24(Aggregation,Asso...)
25(SOLID Principles)
5.Abstraction:
Abstraction is a process of hiding the implementation details and displaying the essential features
Example of Abstraction:
{
doAbstraction();
}
Impl: Abstraction
{
doAbstraction()
{
//Implement it
}
}
1 (oops)
2 (class)
3 (Class & Struct Diff..)
4 (object)
5 (Abstraction)
6 (Encapsulation)
7 (Encaps & Abst Diff..)
8 (Access Specifiers)
9 (specifiers in proper..)
10 (Object And Instance)
11 (pointers in C#)
12 (Inheritance)
13 (Why multi inheri...)
14 (Method Hiding)
15 (Polymorphism)
16 (Cohesion&Coupling)
17 (Coupling..)
18 (Constru & Dest..)
19 (Abst Class&method)
20(Interface)
21(Abst. Class & Int)
22(Use of abst and Int)
23(Static Class & Mem)
24(Aggregation,Asso...)
25(SOLID Principles)
6.Encapsulation:
Encapsulation is the process of hiding the data into the single unit to protect the data from the outside world. Example of encapsulation is a class
1 (oops)
2 (class)
3 (Class & Struct Diff..)
4 (object)
5 (Abstraction)
6 (Encapsulation)
7 (Encaps & Abst Diff..)
8 (Access Specifiers)
9 (specifiers in proper..)
10 (Object And Instance)
11 (pointers in C#)
12 (Inheritance)
13 (Why multi inheri...)
14 (Method Hiding)
15 (Polymorphism)
16 (Cohesion&Coupling)
17 (Coupling..)
18 (Constru & Dest..)
19 (Abst Class&method)
20(Interface)
21(Abst. Class & Int)
22(Use of abst and Int)
23(Static Class & Mem)
24(Aggregation,Asso...)
25(SOLID Principles)
7.Difference between Encapsulation and Abstraction in OOPS:
1.Encapsulation is the process of hiding the data using private and protected access modifier while abstraction is the process of hiding the data implementation
2.Abstraction is implemented using interface and abstract class while Encapsulation is implemented using private and protected access modifier
1 (oops)
2 (class)
3 (Class & Struct Diff..)
4 (object)
5 (Abstraction)
6 (Encapsulation)
7 (Encaps & Abst Diff..)
8 (Access Specifiers)
9 (specifiers in proper..)
10 (Object And Instance)
11 (pointers in C#)
12 (Inheritance)
13 (Why multi inheri...)
14 (Method Hiding)
15 (Polymorphism)
16 (Cohesion&Coupling)
17 (Coupling..)
18 (Constru & Dest..)
19 (Abst Class&method)
20(Interface)
21(Abst. Class & Int)
22(Use of abst and Int)
23(Static Class & Mem)
24(Aggregation,Asso...)
25(SOLID Principles)
8.Access Specifiers:
1.Public: Accessible outside the class through object reference
2.Private: Accessible inside the class only through member functions
3.Protected: Just like private but Accessible in derived classes also through member
functions
4.Internal: Visible inside the assembly. Accessible through objects
5.Protected Internal: Visible inside the assembly through objects and in derived classes outside the assembly through member functions
Non-nested types (Default Access Specifiers):
---
|
Default
|
Permitted declablue accessibilities
namespace
|
public
|
none (always implicitly public)
enum
|
public
|
none (always implicitly public)
interface
|
internal
|
public,internal
class
|
internal
|
public,internal
struct
|
internal
|
public,internal
delegate
|
internal
|
public,internal
abstract class
|
internal
|
public,internal
class Method
|
private
|
public,internal ,private ,protected
struct Method
|
private
|
public,internal,private,protected
constructor
|
private
|
public,internal
Nested type and member accessibilities (Default Access Specifiers):
---
|
Default
|
Permitted declablue accessibilities
namespace
|
public
|
none (always implicitly public)
enum
|
public
|
none (always implicitly public)
interface
|
public
|
none
class
|
private
|
All
struct
|
private
|
public,internal,private
delegate
|
private
|
All
constructor
|
protected
|
All
interface mem
|
public
|
none (always implicitly public)
method
|
private
|
All
field
|
private
|
All
user-def operator
|
none
|
public (must be declablue public)
Examples:
abcStruct
{
}
Error: Elements defined in a namespace cannot be explicitly declablue as private, protected, or protected internal
absClass
{
}
Error: Elements defined in a namespace cannot be explicitly declablue as private, protected, or protected internal
1 (oops)
2 (class)
3 (Class & Struct Diff..)
4 (object)
5 (Abstraction)
6 (Encapsulation)
7 (Encaps & Abst Diff..)
8 (Access Specifiers)
9 (specifiers in proper..)
10 (Object And Instance)
11 (pointers in C#)
12 (Inheritance)
13 (Why multi inheri...)
14 (Method Hiding)
15 (Polymorphism)
16 (Cohesion&Coupling)
17 (Coupling..)
18 (Constru & Dest..)
19 (Abst Class&method)
20(Interface)
21(Abst. Class & Int)
22(Use of abst and Int)
23(Static Class & Mem)
24(Aggregation,Asso...)
25(SOLID Principles)
9.Access specifiers inside properties for set and get:
We can set any access specifier for set or get but can not applied for both set and get simultaneously.
Examples:
public interface IHasInt
{
int TheInt
{
get;
}
public class MyClass : IHasInt
{
public int TheInt
{
get;
private set;
}
public MyClass()
{
TheInt = 123;
}
}
}
In this example, the interface has specified a getter, but not a setter. So when someone has an instance of the interface, they are only allowed to access the value, but cannot alter it.
public string strProp1
{
public get;
public set;
}
Can't specify accessibility modifier for both of the property.
1 (oops)
2 (class)
3 (Class & Struct Diff..)
4 (object)
5 (Abstraction)
6 (Encapsulation)
7 (Encaps & Abst Diff..)
8 (Access Specifiers)
9 (specifiers in proper..)
10 (Object And Instance)
11 (pointers in C#)
12 (Inheritance)
13 (Why multi inheri...)
14 (Method Hiding)
15 (Polymorphism)
16 (Cohesion&Coupling)
17 (Coupling..)
18 (Constru & Dest..)
19 (Abst Class&method)
20(Interface)
21(Abst. Class & Int)
22(Use of abst and Int)
23(Static Class & Mem)
24(Aggregation,Asso...)
25(SOLID Principles)
10.Object And Instance:
Variable for class is an object. When an object is created by using the keyword new, then memory will be allocated for the class in heap memory area, which is called as an instance
1 (oops)
2 (class)
3 (Class & Struct Diff..)
4 (object)
5 (Abstraction)
6 (Encapsulation)
7 (Encaps & Abst Diff..)
8 (Access Specifiers)
9 (specifiers in proper..)
10 (Object And Instance)
11 (pointers in C#)
12 (Inheritance)
13 (Why multi inheri...)
14 (Method Hiding)
15 (Polymorphism)
16 (Cohesion&Coupling)
17 (Coupling..)
18 (Constru & Dest..)
19 (Abst Class&method)
20(Interface)
21(Abst. Class & Int)
22(Use of abst and Int)
23(Static Class & Mem)
24(Aggregation,Asso...)
25(SOLID Principles)
11.Can we use pointers in C#:
To maintain type safety and security, C# does not support pointer arithmetic, by default. However, by using the unsafe keyword, you can define an unsafe context in which pointers can be used.
It is just code whose safety cannot be verified by the CLR. The CLR will therefore only execute unsafe code if it is in a fully trusted assembly. If you use unsafe code, it is your responsibility to ensure that your code does not introduce security risks or pointer errors.
A pointer type declaration takes one of the following forms:
• Any user-defined struct type that contains fields of unmanaged types only.
boxing and unboxing do not support pointers. However, you can convert between different pointer types and between pointer types and integral types.
When you declare multiple pointers in the same declaration, the asterisk (*) is written together with the underlying type only; it is not used as a prefix to each pointer name. For example:
int* p1, p2, p3; // Ok
int *p1, *p2, *p3; // Invalid in C#
A pointer cannot point to a reference or to a struct that contains references, because an object reference can be garbage collected even if a pointer is pointing to it. The garbage collector does not keep track of whether an object is being pointed to by any pointer types.
The value of the pointer variable of type myType* is the address of a variable of type myType. The following are examples of pointer type declarations:
Example
Description
int* p
p is a pointer to an integer.
int** p
p is a pointer to a pointer to an integer.
int*[] p
p is a single-dimensional array of pointers to integers.
char* p
p is a pointer to a char.
void* p
p is a pointer to an unknown type.
int* myVariable;
The expression *myVariable denotes the int variable found at the address contained in myVariable.
// Normal pointer to an object.
int[] a = new int[5] {10, 20, 30, 40, 50};
// Must be in unsafe code to use interior pointers.
unsafe
{
// Must pin object on heap so that it doesn't move while using interior pointers.
fixed (int* p = &a[0])
{
// p is pinned as well as object, so create another pointer to show incrementing it.
int* p2 = p;
Console.WriteLine(*p2);
// Incrementing p2 bumps the pointer by four bytes due to its type ...
p2 += 1;
Console.WriteLine(*p2);
p2 += 1;
Console.WriteLine(*p2);
Console.WriteLine("--------");
Console.WriteLine(*p);
// Deferencing p and incrementing changes the value of a[0] ...
*p += 1;
Console.WriteLine(*p);
*p += 1;
Console.WriteLine(*p);
}
}
Console.WriteLine("--------");
Console.WriteLine(a[0]);
Console.ReadLine();
// Output:
//10
//20
//30
//--------
//10
//11
//12
//--------
//12
You cannot apply the indirection operator to a pointer of type void*. However, you can use a cast to convert a void pointer to any other pointer type, and vice versa.
A pointer can be null. Applying the indirection operator to a null pointer causes an implementation-defined behavior.
Be aware that passing pointers between methods can cause undefined behavior. Examples are returning a pointer to a local variable through an Out or Ref parameter or as the function result. If the pointer was set in a fixed block, the variable to which it points may no longer be fixed.
The following table lists the operators and statements that can operate on pointers in an unsafe context:
Operator/Statement
Use
*
Performs pointer indirection.
->
Accesses a member of a struct through a pointer.
[]
Indexes a pointer.
&
Obtains the address of a variable.
++ and --
Increments and decrements pointers.
+ and -
Performs pointer arithmetic.
==, !=, <, >, <=, and >=
Compares pointers.
stackalloc
Allocates memory on the stack.
fixed statement
Temporarily fixes a variable so that its address may be found.
1 (oops)
2 (class)
3 (Class & Struct Diff..)
4 (object)
5 (Abstraction)
6 (Encapsulation)
7 (Encaps & Abst Diff..)
8 (Access Specifiers)
9 (specifiers in proper..)
10 (Object And Instance)
11 (pointers in C#)
12 (Inheritance)
13 (Why multi inheri...)
14 (Method Hiding)
15 (Polymorphism)
16 (Cohesion&Coupling)
17 (Coupling..)
18 (Constru & Dest..)
19 (Abst Class&method)
20(Interface)
21(Abst. Class & Int)
22(Use of abst and Int)
23(Static Class & Mem)
24(Aggregation,Asso...)
25(SOLID Principles)
12.Inheritance:
Creating a new class from an existing class is called as inheritance. Advantage of inheritance is reusability of the code.
Example:
class SuperCar : car
{
}
Inheritance can be classified to 5 types
1.Single Inheritance
2.Hierarchical Inheritance
3.Multi-Level Inheritance
4.Hybrid Inheritance
5.Multiple Inheritance
1.Single Inheritance
When a single derived class is created from a single base class then the inheritance is called as single inheritance.
BASE
DERIVED
2.Hierarchical Inheritance
When more than one derived class are created from a single base class, then that inheritance is called as hierarchical inheritance.
BASE
DERIVED1
DERIVED1
3.Multi-Level Inheritance
When a derived class is created from another derived class, then that inheritance is called as multi-level inheritance.
BASE
DERIVED1
DERIVED2
4.Hybrid Inheritance
Any combination of single, hierarchical and multi level inheritances is called as hybrid inheritance.
BASE
DERIVED1
DERIVED1
DERIVED1
5.Multiple Inheritances
When a derived class is created from more than one base class then that inheritance is called as multiple inheritances. But multiple inheritances is not supported by .net using classes and can be done using interfaces.
BASE1
BASE2
DERIVED
1 (oops)
2 (class)
3 (Class & Struct Diff..)
4 (object)
5 (Abstraction)
6 (Encapsulation)
7 (Encaps & Abst Diff..)
8 (Access Specifiers)
9 (specifiers in proper..)
10 (Object And Instance)
11 (pointers in C#)
12 (Inheritance)
13 (Why multi inheri...)
14 (Method Hiding)
15 (Polymorphism)
16 (Cohesion&Coupling)
17 (Coupling..)
18 (Constru & Dest..)
19 (Abst Class&method)
20(Interface)
21(Abst. Class & Int)
22(Use of abst and Int)
23(Static Class & Mem)
24(Aggregation,Asso...)
25(SOLID Principles)
13.Why multiple inheritance is not possible in c#
In C++, what’s the diamond problem, and how can it be avoided?
Taking a look at the graphic below helps in explaining the diamond problem.
B==>A<==C , B<==D==>C
Suppose we have 2 classes B and C that derive from the same class – in our example above it would be class A. We also have class D that derives from both B and C by using multiple inheritance. You can see in the figure above that the classes essentially form the shape of a diamond – which is why this problem is called the diamond problem. Now, let’s take the graphic above and make it more concrete by translating it into actual code:
/*
The Animal class below corresponds to class
A in our graphic above
*/
/*
class Animal { /* ... */ }; // base class
{
int weight;
public:
int getWeight() { return weight;};
public:
public:
};
class Tiger : public Animal { /* ... */ };
class Lion : public Animal { /* ... */ }
class Liger : public Tiger, public Lion { /* ... */ };
In the code above, we’ve given a more concrete example of the diamond problem. The Animal class corresponds to the topmost class in the hierarchy (A in our graphic above), Tiger and Lion respectively correspond to B and C in the graphic, and the Liger class corresponds to D.
Now, the question is what is the problem with having an inheritance hierarcy like this. Take a look at the code below so that we can best answer that question:
int main( )
{
Liger lg ;
/*COMPILE ERROR, the code below will not get past
any C++ compiler */
int weight = lg.getWeight();
}
In our inheritance hierarchy, we can see that both the Tiger and Lion classes derive from the Animal base class. And here is the problem: because Liger derives from both the Tiger and Lion classes – which each have their own copy of the data members and methods of the Animal class- the Liger object "lg" will contain two subobjects of the Animal base class.
So, you ask, what’s the problem with a Liger object having 2 sub-objects of the Animal class? Take another look at the code above – the call "lg.getWeight()" will result in a compiler error. This is because the compiler does not know whether the call to getWeight refers to the copy of getWeight that the Liger object lg inherited through the Lion class or the copy that lg inherited through the Tiger class. So, the call to getWeight in the code above is ambiguous and will not get past the compiler.
Solution to the Diamond Problem
We’ve given an explanation of the diamond problem, but now we want to give you a solution to the diamond problem. If the inheritance from the Animal class to both the Lion class and the Tiger class is marked as virtual, then C++ will ensure that only one subobject of the Animal class will be created for every Liger object. This is what the code for that would look like:
class Tiger : virtual public Animal { /* ... */ };
class Lion : virtual public Animal { /* ... */ }
You can see that the only change we’ve made is to add the "virtual" keyword to the Tiger and Lion class declarations. Now the Liger class object will have only one Animal subobject, and the code below will compile just fine:
int main( )
{
/*THIS CODE WILL NOW COMPILE OK NOW THAT WE'VE
USED THE VIRTUAL KEYWORD IN THE TIGER AND LION
CLASS DECLARATIONS */
int weight = lg.getWeight();
}
Multiple inheritance problem is solved by interfaces in c#
interface I1
{
void aa();
}
interface I2
{
void aa();
}
public class c1 : I1,I2
{
void I1.aa()
{
}
void I2.aa()
{
}
}
1 (oops)
2 (class)
3 (Class & Struct Diff..)
4 (object)
5 (Abstraction)
6 (Encapsulation)
7 (Encaps & Abst Diff..)
8 (Access Specifiers)
9 (specifiers in proper..)
10 (Object And Instance)
11 (pointers in C#)
12 (Inheritance)
13 (Why multi inheri...)
14 (Method Hiding)
15 (Polymorphism)
16 (Cohesion&Coupling)
17 (Coupling..)
18 (Constru & Dest..)
19 (Abst Class&method)
20(Interface)
21(Abst. Class & Int)
22(Use of abst and Int)
23(Static Class & Mem)
24(Aggregation,Asso...)
25(SOLID Principles)
14.Method Hiding
If you want your derived member to have the same name as a member in a base class, but you do not want it to participate in virtual invocation, you can use the new keyword. The new keyword is put before the return type of a class member that is being replaced.
The child class is hiding the base class method. This is called method hiding
Example:
using
System;
public
class
Parent
{
public
void
Write ()
{
Console.WriteLine ("Parent
Class write method");
}
}
public
class
Child:
Parent
{
public
new
void
Write ()
{
Console.WriteLine ("Child
Class write method");
}
public
static
void
Main
()
{
Child
C1 =
new
Child
();
C1.Write (); // Calls the
new
method =>
Child
Class write method
((Parent) C1).Write
();//Type caste C1 to be of type
Parent
and call Write ()
Method=>
Parent
Class write method
Parent
P1 = (Parent)C1;
P1.Write();
// Calls the old method=>
Parent
Class write method
Parent
P1 =
new
Child
();
P1.Write(); // Calls the old method=>
Parent
Class write method
Child
P1 =
new
Parent();
P1.Write();// Error: Cannot implicitly convert type
Parent
to
Child.
}
}
1 (oops)
2 (class)
3 (Class & Struct Diff..)
4 (object)
5 (Abstraction)
6 (Encapsulation)
7 (Encaps & Abst Diff..)
8 (Access Specifiers)
9 (specifiers in proper..)
10 (Object And Instance)
11 (pointers in C#)
12 (Inheritance)
13 (Why multi inheri...)
14 (Method Hiding)
15 (Polymorphism)
16 (Cohesion&Coupling)
17 (Coupling..)
18 (Constru & Dest..)
19 (Abst Class&method)
20(Interface)
21(Abst. Class & Int)
22(Use of abst and Int)
23(Static Class & Mem)
24(Aggregation,Asso...)
25(SOLID Principles)
15.Polymorphism:
Polymorphism means having more than one form. An operation that exhibit different behavior
On different situation.Polymorphism can be achieved with the help of overloading and overriding concepts. Polymorphism is classified into compile time polymorphism and runtime polymorphism.
It has two distinct aspects:
1.At run time, objects of a derived class may be treated as objects of a base class in places such as method parameters and collections or arrays. When this occurs, the object's declared type is no longer identical to its run-time type.
2.Base classes may define and implement virtual methods, and derived classes can override them, which means they provide their own definition and implementation. At run-time, when client code calls the method, the CLR looks up the run-time type of the object, and invokes that override of the virtual method. Thus in your source code you can call a method on a base class, and cause a derived class's version of the method to be executed.
Polymorphism is of two types:
1.Compile time polymorphism/Overloading
2.Runtime polymorphism/Overriding
1.Compile Time Polymorphism
Compile time polymorphism is method overloading. It is also called early binding.In method overloading method performs the different task at the different input parameters.
It is also defined as same name method with different signature.
2.Runtime Time Polymorphism
Runtime time polymorphism is done using inheritance and virtual functions. Method overriding is called runtime polymorphism. It is also called late binding.
When overriding a method, you change the behavior of the method for the derived class. Overloading a method simply involves having another method with the same prototype.
Method Overloading
It is the same name method with different signature
Example:
Public void Area(float l, float b)
{
float x = (float)l* b;
// here we have used function overload with 2 parameters.
Console.WriteLine ("Area of a rectangle: {0}",x);
}
public void Area(float a, float b, float c)
{
float s = (float)(a*b*c)/2;
// here we have used function overload with 3 parameters.
Console.WriteLine ("Area of a circle: {0}", s);
}
Method Overriding
Overriding means changing the functionality of a method without changing the signature. We can override a function in base class by creating a similar function in derived class. This is done by using virtual/override keywords.
Example
// Base class
public class BaseClass
{
public virtual void Method1()
{
Console.Write("Base Class Method");
}
}
// Derived class
public class DerivedClass : BaseClass
{
public override void Method1()
{
Console.Write("Derived Class Method");
}
}
// Using base and derived class
public class Sample
{
public void TestMethod()
{
//calling the overriden method
DerivedClass objDC = new DerivedClass();
objDC.Method1();
//calling the baesd class method
BaseClass objBC = (BaseClass)objDC;
objDC.Method1();
}
}
public
class
Shape
{
// A few example members
public
int
X
{
get;
private
set;
}
public
int
Y
{
get;
private
set;
}
public
int
Height
{
get;
set;
}
public
int
Width
{
get;
set;
}
//
Virtual method
public
virtual
void
Draw()
{
Console.WriteLine("Performing
base
class
drawing tasks");
}
}
class
Circle :
Shape
{
public
override
void
Draw()
{
// Code to draw a circle...
Console.WriteLine("Drawing a circle");
base.Draw();
}
}
class
Rectangle
:
Shape
{
public
override
void
Draw()
{
// Code to draw a rectangle...
Console.WriteLine("Drawing a rectangle");
base.Draw();
}
}
class
Triangle :
Shape
{
public
override
void
Draw()
{
// Code to draw a triangle...
Console.WriteLine("Drawing a triangle");
base.Draw();
}
}
class
Program
{
static
void
Main(string[] args)
{
// Polymorphism at work #1: a
Rectangle, Triangle and Circle
//
can all be used whereever a
Shape
is
expected. No cast
is
//
required because an
implicit
conversion exists from a derived
//
class
to its
base
class.
System.Collections.Generic.List<Shape>
shapes =
new
System.Collections.Generic.List<Shape>();
shapes.Add(new
Rectangle());
shapes.Add(new
Triangle());
shapes.Add(new
Circle());
//
Polymorphism at work #2: the
virtual
method Draw
is
//
invoked on each of the derived classes, not the
base
class.
foreach
(Shape
s
in
shapes)
{
s.Draw();
}
//
Keep the console open
in
debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
Drawing a rectangle
Performing
base
class
drawing tasks
Drawing a triangle
Performing
base
class
drawing tasks
Drawing a circle
Performing
base
class
drawing tasks
*/
class
Program
{
static
void
Main(string[] args)
{
System.Collections.Generic.List<Shape>
shapes =
new
System.Collections.Generic.List<Shape>();
shapes.Add(new
Rectangle());
shapes.Add(new
Circle());
//
Polymorphism at work #2: the
virtual
method Draw
is
//
invoked on each of the derived classes, not the
base
class.
foreach
(Shape
s
in
shapes)
{
s.Draw();
}
//
Keep the console open
in
debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
Console.ReadLine();
}
}
public
class
Shape
{
// A few example members
public
int
X
{
get;
private
set;
}
public
int
Y
{
get;
private
set;
}
public
int
Height
{
get;
set;
}
public
int
Width
{
get;
set;
}
//
Virtual method
public
virtual
void
Draw()
{
Console.WriteLine("Performing
base
class
drawing tasks");
}
}
class
Circle :
Shape
{
public
override
void
Draw()
{
// Code to draw a circle...
Console.WriteLine("Drawing a circle");
base.Draw();
}
}
class
Rectangle
: Circle
{
public
override
void
Draw()
{
// Code to draw a rectangle...
Console.WriteLine("Drawing a rectangle");
base.Draw();
}
}
OUTPUT:
Drawing a rectangle
Drawing a circle
Performing
base
class
drawing tasks
Drawing a circle
Performing
base
class
drawing tasks
Virtual Members
When a derived class inherits from a base class, it gains all the methods, fields, properties and events of the base class. The designer of the derived class can choose whether to
•override virtual members in the base class,
•inherit the closest base class method without overriding it
•define new non-virtual implementation of those members that hide the base class implementations
A derived class can override a base class member only if the base class member is declared as virtual or abstract. The derived member must use the override keyword to explicitly indicate that the method is intended to participate in virtual invocation
Example
class
Program
{
static
void
Main(string[] args)
{
DerivedClass
B =
new
DerivedClass();
B.DoWork(); // Calls the
new
method.
BaseClass
A = (BaseClass)B;
A.DoWork(); // Also calls the
new
method.
BaseClass
A1 =
new
DerivedClass();
A.DoWork();
//DerivedClass
A2 =
new
BaseClass();
//A.DoWork();
Console.ReadLine();
}
}
public
class
BaseClass
{
public
virtual
void
DoWork()
{
Console.WriteLine("BaseClass");
}
public
virtual
int
WorkProperty
{
get
{
return
0;
}
}
}
public
class
DerivedClass
:
BaseClass
{
public
override
void
DoWork()
{
Console.WriteLine("DerivedClass");
}
public
override
int
WorkProperty
{
get
{
return
0;
}
}
}
Output:
DerivedClass
DerivedClass
DerivedClass
Preventing Derived Classes from Overriding Virtual Members
A derived class can stop virtual inheritance by declaring an override as sealed. This requires putting the sealed keyword before the override keyword in the class member declaration.
Example
public
class
A
{
public
virtual
void
DoWork()
{
}
}
public
class
B : A
{
public
override
void
DoWork()
{
}
}
public
class
C : B
{
public
sealed
override
void
DoWork()
{
}
}
In the above example, the method DoWork is no longer virtual to any class derived from C. It is still virtual for instances of C, even if they are cast to type B or type A. Sealed methods can be replaced by derived classes by using the new keyword, as the following example shows:
public
class
D : C
{
public
new
void
DoWork()
{
}
}
Accessing Base Class Virtual Members from Derived Classes
A derived class that has replaced or overridden a method or property can still access the method or property on the base class using the base keyword.
Example
public
class
Base
{
public
virtual
void
DoWork()
{
/*...*/
}
}
public
class
Derived : Base
{
public
override
void
DoWork()
{
//Perform Derived's work here
//...
//
Call DoWork on
base
class
base.DoWork();
}
}
1 (oops)
2 (class)
3 (Class & Struct Diff..)
4 (object)
5 (Abstraction)
6 (Encapsulation)
7 (Encaps & Abst Diff..)
8 (Access Specifiers)
9 (specifiers in proper..)
10 (Object And Instance)
11 (pointers in C#)
12 (Inheritance)
13 (Why multi inheri...)
14 (Method Hiding)
15 (Polymorphism)
16 (Cohesion&Coupling)
17 (Coupling..)
18 (Constru & Dest..)
19 (Abst Class&method)
20(Interface)
21(Abst. Class & Int)
22(Use of abst and Int)
23(Static Class & Mem)
24(Aggregation,Asso...)
25(SOLID Principles)
16.Cohesion and Coupling :
Cohesion
The concept of cohesion shows to what degree a program’s or a component’s various tasks and responsibilities are related to one another, i.e. how much a program is focused on solving a single problem. Cohesion is divided into strong cohesion and weak cohesion.
Strong Cohesion
Strong cohesion indicates that the responsibilities and tasks of a piece of code (a method, class, component or a program) are related to one another and intended to solve a common problem. This is something we must always aim for. Strong cohesion is a typical characteristic of high-quality software.
Strong Cohesion in a Class
Strong cohesion in a class indicates that the class defines only one entity. We mentioned earlier that an entity can have many roles (Peter is a soldier, husband and a taxpayer). Each of these roles is defined in the same class. Strong cohesion indicates that the class solves only one task, one problem, and not many at the same time.
A class, which does many things at the same time, is difficult to understand and maintain. Consider a class, which implements a hash table, provides functions for printing, sending an e-mail and working with trigonometric functions all at once. How do we name such a class? If we find it difficult to answer this question, this means that we have failed to achieve strong cohesion and have to separate the class into several smaller classes, each solving a single task.
Strong Cohesion in a Class – Example
As an example of strong cohesion we can point out the System.Math class. It performs a single task: it provides mathematical calculations and constants:
- Sin(), Cos(), Asin()
- Sqrt(), Pow(), Exp()
- Math.PI, Math.E
Strong Cohesion in a Method
A method is well written when it performs only one task and performs it well. A method, which does a lot of work related to different things, has bad cohesion. It has to be broken down into simpler methods, each solving only one task. Once again, the question is posed what name should we give to a method, which finds prime numbers, draws 3D graphics on the screen, communicates with the network and prints records extracted from a data base? Such a method has bad cohesion and has to be logically separated into several methods.
Weak Cohesion
Weak cohesion is observed along with methods, which perform several unrelated tasks. Such methods take several different groups of parameters, in order to perform different tasks. Sometimes, this requires logically unrelated data to be unified for the sake of such methods. Weak cohesion is harmful and must be avoided!
Weak Cohesion – Example
Here is a sample class with weak cohesion:
public class Sample
{
public void PrintDocument(Document d) { … }
public void SendEmail(string recipient,
string subject, string text) { … }
public void CalculateDistanceBetweenPoints(
int x1, int y1, int x2, int y2) { … }
}
Best Practices with Cohesion
Strong cohesion is quite logically the "good" way of writing code. The concept is associated with simpler and clearer source code – code that is easier to maintain and reuse (because of the fewer tasks it has to perform).
Contrarily, with weak cohesion each change is a ticking time bomb, because it could affect other functionality. Sometimes a logical task is spread out to several different modules and thus changing it is more labor intensive. Code reuse is also difficult, because a component does several unrelated tasks and to reuse it the exact same conditions must be met which is hard to achieve.
1 (oops)
2 (class)
3 (Class & Struct Diff..)
4 (object)
5 (Abstraction)
6 (Encapsulation)
7 (Encaps & Abst Diff..)
8 (Access Specifiers)
9 (specifiers in proper..)
10 (Object And Instance)
11 (pointers in C#)
12 (Inheritance)
13 (Why multi inheri...)
14 (Method Hiding)
15 (Polymorphism)
16 (Cohesion&Coupling)
17 (Coupling..)
18 (Constru & Dest..)
19 (Abst Class&method)
20(Interface)
21(Abst. Class & Int)
22(Use of abst and Int)
23(Static Class & Mem)
24(Aggregation,Asso...)
25(SOLID Principles)
17.Coupling
Coupling mostly describes the extent to which components / classes depend on one another. It is broken down into loose coupling and tight coupling. Loose coupling usually correlates with strong cohesion and vice versa.
1.Loose Coupling
Loose coupling is defined by a piece of code’s (program / class / component) communication with other code through clearly defined interfaces (contracts). A change in the implementation of a loosely coupled component doesn’t reflect on the others it communicates with. When you write source code, you must not rely on inner characteristics of components (specific behavior that is not described by interfaces).
The contract has to be maximally simplified and define only the requiblue behavior for this component’s work by hiding all unnecessary details.
Loose coupling is a code characteristic you should aim for. It is one of the characteristics of high-quality programming code.
Loose Coupling – Example
Here is an example of loose coupling between classes and methods:
class Report
{
public bool LoadFromFile(string fileName) { … }
public bool SaveToFile(string fileName) { … }
}
class Printer
{
public static int Print(Report report) { … }
}
class Example
{
static void Main()
{
Report myReport = new Report();
myReport.LoadFromFile("DailyReport.xml");
Printer.Print(myReport);
}
}
In this example, none of the methods depend on the others. The methods rely only on some of the parameters, which are passed to them. Should we need one of the methods in a next project, we could easily take it out and reuse it.
2.Tight Coupling
We achieve tight coupling when there are many input parameters and output parameters; when we use undocumented (in the contract) characteristics of another component (for example, a dependency on static fields in another class); and when we use many of the so called control parameters that indicate behavior with actual data. Tight coupling between two or more methods, classes or components means that they cannot work independently of one another and that a change in one of them will also affect the rest. This leads to difficult to read code and big problems with its maintenance.
Tight Coupling – Example
Here is an example of tight coupling between classes and methods:
class MathParams
{
public static double operand;
public static double result;
}
class MathUtil
{
public static void Sqrt()
{
MathParams.result = CalcSqrt(MathParams.operand);
}
}
class SpaceShuttle
{
static void Main()
{
MathParams.operand = 64;
MathUtil.Sqrt();
Console.WriteLine(MathParams.result);
}
}
Such code is difficult to understand and maintain, and the likelihood of mistakes when using it is great. Think about what happens if another method, which calls Sqrt(), passes its parameters through the same static variables operand and result.
If we have to use the same functionality for deriving square root in a subsequent project, we will not be able to simply copy the method Sqrt(), but rather we will have to copy the classes MathParams and MathUtil together with all of their methods. This makes the code difficult to reuse.
In fact, the above code is an example of bad code according to all rules of Procedural and Object-Oriented Programming and if you think twice, you will certainly identify at least several more disregarded recommendations from those we have given you so far.
Best Practices with Coupling
The most common and advisable way of invoking a well written module’s functionality is through interfaces. That way, the functionality can be substituted without clients of the code requiring changes. The jargon expression for this is "programming against interfaces".
Most commonly, an interface describes a "contract" observed by this module. It is good practice not to rely on anything else other than what’s described by this contract. The use of inner classes, which are not part of the public interface of a module, is not recommended because their implementation can be substituted without substituting the contract (we already discussed this in the section "Abstraction").
It is good practice that the methods are made flexible and ready to work with all components, which observe their interfaces, and not only with definitive ones (i.e. to have implicit requirements). The latter would mean that these methods expect something specific from the components they can work with. It is also good practice that all dependencies are clearly described and visible. Otherwise, the maintenance of such code becomes difficult (it is riddled with stumbling-blocks).
A good example of strong cohesion and loose coupling we can find in the classes from the standard namespaces System.Collections and System.Collections.Generic. These .NET classes for working with collections have strong cohesion. Each solves a single problem and allows easy reuse. These classes have another characteristic of high-quality programming code: loose coupling. The classes, implementing the collections, are not related to one another. Each works through a strictly defined interface and does not give away details of its implementation. All methods and fields not from the interface are hidden, in order to blueuce the possibility of coupling with them. Methods in the collection classes do not depend on static variables and do not rely on any input data except for their inner state and passed parameters. This is good practice every programmer sooner or later attains with gained experience.
1 (oops)
2 (class)
3 (Class & Struct Diff..)
4 (object)
5 (Abstraction)
6 (Encapsulation)
7 (Encaps & Abst Diff..)
8 (Access Specifiers)
9 (specifiers in proper..)
10 (Object And Instance)
11 (pointers in C#)
12 (Inheritance)
13 (Why multi inheri...)
14 (Method Hiding)
15 (Polymorphism)
16 (Cohesion&Coupling)
17 (Coupling..)
18 (Constru & Dest..)
19 (Abst Class&method)
20(Interface)
21(Abst. Class & Int)
22(Use of abst and Int)
23(Static Class & Mem)
24(Aggregation,Asso...)
25(SOLID Principles)
18.Constructors and Destructors:
Constructors have the same name as the class or struct, and they usually initialize the data members of the new object. Constructors and destructors are special member functions of classes that are used to construct and destroy class objects. Construction may involve memory allocation and initialization for objects. Destruction may involve cleanup and deallocation of memory for objects.
1.Constructors and destructors do not have return types nor can they return values.
2.References and pointers cannot be used on constructors and destructors because their addresses cannot be taken.
3.Constructors cannot be declared with the keyword virtual.
4.Constructors and destructors cannot be declared const, or volatile.
5.Unions cannot contain class objects that have constructors or destructors.
The compiler automatically calls constructors when defining class objects and calls destructors when class objects go out of scope. A constructor does not allocate memory for the class object it’s this pointer refers to, but may allocate storage for more objects than its class object refers to. If memory allocation is required for objects, constructors can explicitly call the new operator. During cleanup, a destructor may release objects allocated by the corresponding constructor.
Example of Constructor
class C
{
private int x;
private int y;
public C (int i, int j)
{
x = i;
y = j;
}
public void display ()
{
Console.WriteLine(x + "i+" + y);
}
}
Example of Destructor
class D
{
public D ()
{
// constructor
}
~D ()
{
// Destructor
}
}
The class parameterized constructor can invoke the constructor of the base class through the initializer, as follows:
class Circle : Shape
{
public Circle(double radius): base(radius, 0)
{
}
}
The order in which the object’s fields and constructors are initialized:
1.Derived static fields
2.Derived static constructor
3.Derived instance fields
4.Base static fields
5.Base static constructor
6.Base instance fields
7.Base instance constructor
8.Derived instance constructor
Example:
using System;
namespace ObjectInit
{
class Program
{
static void Main( string[] args )
{
Derived d = new Derived();
Console.ReadLine();
}
}
class Base
{
public Base()
{
Console.WriteLine( "Base.Instance.Constructor" );
this.m_Field3 = new Tracker( "Base.Instance.Field3");
this.Virtual();
}
static Base()
{
Console.WriteLine( "Base.Static.Constructor" );
}
private Tracker m_Field1 = new Tracker("Base.Instance.Field1" );
private Tracker m_Field2 = new Tracker("Base.Instance.Field2" );
private Tracker m_Field3;
static private Tracker s_Field1 = new Tracker( "Base.Static.Field1");
static private Tracker s_Field2 = new Tracker( "Base.Static.Field2");
Following is the console output from this sample program:
Derived.Static.Field1
Derived.Static.Field2
Derived.Static.Constructor
Derived.Instance.Field1
Derived.Instance.Field2
Base.Static.Field1
Base.Static.Field2
Base.Static.Constructor
Base.Instance.Field1
Base.Instance.Field2
Base.Instance.Constructor
Base.Instance.Field3
Derived.Instance.Virtual
Derived.Instance.Constructor
Derived.Instance.Field3
Types of Constructors:
1.Instance Constructor
2.Private Constructor
3.Static Constructor
1.Instance Constructor:
Instance constructors are used to create and initialize any instance member variables when you use the new expression to create an object of a class.
Example:
class CoOrds
{
public int x, y;
// constructor
public CoOrds()
{
x = 0;
y = 0;
}
}
2.Private Constructor:
It is generally used in classes that mostly contain static members only , it can contain non static methods but that cannot be called from outside the class. If a class has one or more private constructors and no public constructors, other classes (except nested classes) cannot create instances of this class.
Private constructors are used to prevent creating instances of a class when there are no instance fields or methods
Note:
If you do not use an access modifier with the constructor it will still be private by default
Example:
class NLog
{
// Private Constructor:
private NLog() { }
public static double e = Math.E; //2.71828...
}
NOTE:
During inheritance, if the base class contains only parameterized constructor, then derived class must contain a parameterized constructor even it doesn’t need one.
If we tried to access any member of the class where constructor is private then it will show compilation error. Can’t access the member because of protection level.
3.Static Constructor:
A static constructor is used to initialize any static data, or to perform a particular action that needs to be performed once only. It is called automatically before the first instance is created or any static members are referenced.
Suppose we are creating the two objects of class SimpleClass.The constructor will call once.
Example with output :
SimpleClass objSimpleClass = new SimpleClass ();objSimpleClass.cc();
SimpleClass objSimpleClass = new SimpleClass();objSimpleClass.cc();
Output:
SimpleClass constructor called
CC called
CC called
How to: Write a Copy Constructor
The Person class defines a copy constructor that takes, as its argument, an instance of Person. The values of the properties of the argument are assigned to the properties of the new instance of Person. The code contains an alternative copy constructor that sends the Name and Age properties of the instance that you want to copy to the instance constructor of the class.
class Person
{
// Copy constructor.
public Person(Person previousPerson)
{
Name = previousPerson.Name;
Age = previousPerson.Age;
}
// Instance constructor.
public Person(string name, int age)
{
Name = name;
Age = age;
}
public int Age
{
get;
set;
}
public string Name
{
get;
}
public string Details()
{
return Name + " is " + Age.ToString();
}
}
class TestPerson
{
static void Main()
{
// Create a Person object by using the instance constructor.
Person person1 = new Person("George", 40);
// Create another Person object, copying person1.
Person person2 = new Person(person1);
// Change each person's age.
person1.Age = 39;
person2.Age = 41;
// Change person2's name.
person2.Name = "Charles";
// Show details to verify that the name and age fields are distinct.
Console.WriteLine(person1.Details());
Console.WriteLine(person2.Details());
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
// Output:
// George is 39
// Charles is 41
1 (oops)
2 (class)
3 (Class & Struct Diff..)
4 (object)
5 (Abstraction)
6 (Encapsulation)
7 (Encaps & Abst Diff..)
8 (Access Specifiers)
9 (specifiers in proper..)
10 (Object And Instance)
11 (pointers in C#)
12 (Inheritance)
13 (Why multi inheri...)
14 (Method Hiding)
15 (Polymorphism)
16 (Cohesion&Coupling)
17 (Coupling..)
18 (Constru & Dest..)
19 (Abst Class&method)
20(Interface)
21(Abst. Class & Int)
22(Use of abst and Int)
23(Static Class & Mem)
24(Aggregation,Asso...)
25(SOLID Principles)
19.Abstract Classes and Abstract Methods in C#.NET:
1.Abstract Class:
Abstract classes are one of the essential behaviors provided by .NET. Commonly, you would like to make classes that only represent base classes, and don’t want anyone to create objects of these class types. You can make use of abstract classes to implement such functionality in C# using the modifier 'abstract'.
Example:
abstract class absClass
{
}
A sample program that explains abstract classes:
using System;
namespace abstractSample
{
//Creating an Abstract Class
abstract class absClass
{
//A Non abstract method
public int AddTwoNumbers(int Num1, int Num2)
{
return Num1 + Num2;
}
//An abstract method, to be
//overridden in derived class
public abstract int MultiplyTwoNumbers(int Num1, int Num2);
}
abstract class absClass
{
//A Non abstract method
public int AddTwoNumbers(int Num1, int Num2)
{
return Num1 + Num2;
}
//An abstract method, to be
//overridden in derived class
public abstract int MultiplyTwoNumbers(int Num1, int Num2);
}
}
2.Abstract properties:
//Abstract Class with abstract properties
abstract class absClass
{
protected int myNumber;
public abstract int numbers
{
get;
set;
}
}
class absDerived : absClass
{
//Implementing abstract properties
public override int numbers
{
get
{
return myNumber;
}
set
{
myNumber = value;
}
}
}
3.Important rules applied to abstract classes
//Incorrect
//An abstract class cannot be a sealed class
abstract sealed class absClass
{
}
//Incorrect
//An abstract method cannot be private.
private abstract int MultiplyTwoNumbers();
//Incorrect
//An abstract method cannot have the modifier virtual. Because an abstract method is implicitly //virtual.
public abstract virtual int MultiplyTwoNumbers();
//Incorrect
//An abstract member cannot be static.
public abstract static int MultiplyTwoNumbers();
Note:
It is mandatory to override abstract method in the derived class.
It is mandatory to give defination to non abstract method in abstract class.
Abstract class can have Variables and properties.
1 (oops)
2 (class)
3 (Class & Struct Diff..)
4 (object)
5 (Abstraction)
6 (Encapsulation)
7 (Encaps & Abst Diff..)
8 (Access Specifiers)
9 (specifiers in proper..)
10 (Object And Instance)
11 (pointers in C#)
12 (Inheritance)
13 (Why multi inheri...)
14 (Method Hiding)
15 (Polymorphism)
16 (Cohesion&Coupling)
17 (Coupling..)
18 (Constru & Dest..)
19 (Abst Class&method)
20(Interface)
21(Abst. Class & Int)
22(Use of abst and Int)
23(Static Class & Mem)
24(Aggregation,Asso...)
25(SOLID Principles)
20.Interface
Interface is a type which contains only the signatures of methods, delegates or events, it has no implementation.
Implementation of the methods is done by the class that which implements the interface.
It provides a way to achieve runtime polymorphism.
An interface has the following properties:
•An interface is like an abstract base class. Any class or struct that implements the interface must implement all its members.
•An interface can't be instantiated directly. Its members are implemented by any class or struct that implements the interface.
•Interfaces can contain events, indexers, methods, and properties.
•Interfaces contain no implementation of methods.
•A class or struct can implement multiple interfaces. A class can inherit a base class and also implement one or more interfaces.
•Datatype variable can not be declared on abstract.(Ex. Public abstract int i;).
P2.cs(11,8): error CS0531: 'abc.xyz()': interface members cannot have a
definition
Program3
class Demo
{
public static void Main()
{
System.Console.WriteLine("Hello Interfaces");
}
}
interface abc
{
void xyz();
}
Hello Interfaces
Program4
class Demo : abc
{
public static void Main()
{
System.Console.WriteLine("Hello Interfaces");
}
}
interface abc
{
void xyz();
}
Output
P4.cs(1,7): error CS0535: 'Demo' does not implement interface member
'abc.xyz()'
P4.cs(11,8): (Location of symbol related to previous error)
Program5
class Demo : abc
{
public static void Main()
{
System.Console.WriteLine("Hello Interfaces");
}
void xyz()
{
System.Console.WriteLine("In xyz");
}
}
interface abc
{
void xyz();
}
Output
a.cs(1,7): error CS0536: 'Demo' does not implement interface member
'abc.xyz()'.'Demo.xyz()' is either static, not public,
or has the wrong return type.
a.cs(16,8): (Location of symbol related to previous error)
a.cs(7,8): (Location of symbol related to previous error)
Program6
class Demo : abc
{
public static void Main()
{
System.Console.WriteLine("Hello Interfaces");
xyz();
}
public void xyz()
{
System.Console.WriteLine("In xyz");
}
}
interface abc
{
void xyz();
}
Output
Hello Interfaces
In xyz
Program7
class Demo : abc
{
public static void Main()
{
System.Console.WriteLine("Hello Interfaces");
Demo refDemo = new Demo();
refDemo.xyz();
Sample refSample = new Sample();
refSample.xyz();
}
public void xyz()
{
System.Console.WriteLine("In Demo :: xyz");
}
}
interface abc
{
void xyz();
}
class Sample : abc
{
public void xyz()
{
System.Console.WriteLine("In Sample :: xyz");
}
}
Output
In Demo :: xyz
In Sample :: xyz
Program8
class Demo : abc
{
public static void Main()
{
System.Console.WriteLine("Hello Interfaces");
abc refabc = new Demo();
refabc.xyz();
abc refabc = new Sample();
refabc.xyz();
}
public void xyz()
{
System.Console.WriteLine("In Demo :: xyz");
}
}
interface abc
{
void xyz();
}
class Sample : abc
{
public void xyz()
{
System.Console.WriteLine("In Sample :: xyz");
}
}
Output
In Demo :: xyz
In Sample :: xyz
Program9
class Demo : abc
{
public static void Main()
{
abc[] refabc = { new Demo(), new Sample() };
for (int i = 0; i <= 1; i++)
refabc[i].xyz();
}
public void xyz()
{
System.Console.WriteLine("In Demo :: xyz");
}
}
interface abc
{
void xyz();
}
class Sample : abc
{
public void xyz()
{
System.Console.WriteLine("In Sample :: xyz");
}
}
Output
In Demo :: xyz
In Sample :: xyz
Program10
class Demo : abc, def
{
public static void Main()
{
System.Console.WriteLine("Hello Interfaces");
abc refabc = new Demo();
refabc.xyz();
}
public void xyz()
{
System.Console.WriteLine("In xyz");
}
public void pqr()
{
System.Console.WriteLine("In xyz");
}
}
interface abc
{
void xyz();
}
interface def
{
void pqr();
}
Output
Hello Interfaces
In xyz
Program11
class Demo : abc, def
{
public static void Main()
{
System.Console.WriteLine("Hello Interfaces");
abc refabc = new Demo();
refabc.xyz();
refabc.pqr();
}
public void xyz()
{
System.Console.WriteLine("In xyz");
}
public void pqr()
{
System.Console.WriteLine("In xyz");
}
}
interface abc
{
void xyz();
}
interface def
{
void pqr();
}
Output
P11.cs(9,5): error CS0117: 'abc' does not contain a definition for 'pqr'
Program12
class Demo : abc, def
{
public static void Main()
{
System.Console.WriteLine("Hello Interfaces");
Demo refDemo = new Demo();
abc refabc = refDemo;
refabc.xyz();
def refdef = refDemo;
refdef.pqr();
}
public void xyz()
{
System.Console.WriteLine("In xyz");
}
public void pqr()
{
System.Console.WriteLine("In pqr");
}
}
interface abc
{
void xyz();
}
interface def
{
void pqr();
}
Output
Hello Interfaces
In xyz
In pqr
Program14
class Demo : abc, def
{
public static void Main()
{
System.Console.WriteLine("Hello Interfaces");
Demo refDemo = new Demo();
abc refabc = refDemo;
refabc.xyz();
def refdef = refDemo;
refdef.xyz();
}
public void abc.xyz()
{
System.Console.WriteLine("In abc.xyz");
}
public void def.xyz()
{
System.Console.WriteLine("In def.xyz");
}
}
interface abc
{
void xyz();
}
interface def
{
void xyz();
}
Output
a.cs(13,15): error CS0106: The modifier 'public' is not valid for this item
a.cs(18,15): error CS0106: The modifier 'public' is not valid for this item
Program15
class Demo : abc, def
{
public static void Main()
{
System.Console.WriteLine("Hello Interfaces");
Demo refDemo = new Demo();
abc refabc = refDemo;
refabc.xyz();
def refdef = refDemo;
refdef.xyz();
}
void abc.xyz()
{
System.Console.WriteLine("In abc.xyz");
}
void def.xyz()
{
System.Console.WriteLine("In def.xyz");
}
}
interface abc
{
void xyz();
}
interface def
{
void xyz();
}
Output
Hello Interfaces
In abc.xyz
In def.xyz
Program16
class Demo : def
{
public static void Main()
{
System.Console.WriteLine("Hello Interfaces");
Demo refDemo = new Demo();
def refdef = refDemo;
refdef.xyz();
refdef.pqr();
}
public void xyz()
{
System.Console.WriteLine("In xyz");
}
public void pqr()
{
System.Console.WriteLine("In pqr");
}
}
interface abc
{
void xyz();
}
interface def : abc
{
void pqr();
}
Output
Hello Interfaces
In xyz
In pqr
Program17
class Demo : def
{
public static void Main()
{
System.Console.WriteLine("Hello Interfaces");
Demo refDemo = new Demo();
def refdef = refDemo;
refdef.xyz();
refdef.pqr();
}
void def.xyz()
{
System.Console.WriteLine("In xyz");
}
void def.pqr()
{
System.Console.WriteLine("In pqr");
}
}
interface abc
{
void xyz();
}
interface def : abc
{
void pqr();
}
Output
P17.cs(12,8): error CS0539: 'def.xyz' in explicit interface declaration is
not a member of interface
P17.cs(29,11): (Location of symbol related to previous error)
P17.cs(1,7): error CS0535: 'Demo' does not implement interface member
'abc.xyz()'
P17.cs(26,8): (Location of symbol related to previous error)
Program18
class Demo : def
{
public static void Main()
{
System.Console.WriteLine("Hello Interfaces");
Demo refDemo = new Demo();
def refdef = refDemo;
refdef.xyz();
refdef.pqr();
}
void abc.xyz()
{
System.Console.WriteLine("In xyz");
}
void def.pqr()
{
System.Console.WriteLine("In pqr");
}
}
interface abc
{
void xyz();
}
interface def : abc
{
void pqr();
}
Output
Hello Interfaces
In xyz
In pqr
Program19
class Demo : def
{
public static void Main()
{
System.Console.WriteLine("Hello Interfaces");
Demo refDemo = new Demo();
refDemo.xyz();
refDemo.pqr();
}
void abc.xyz()
{
System.Console.WriteLine("In xyz");
}
void def.pqr()
{
System.Console.WriteLine("In pqr");
}
}
interface abc
{
void xyz();
}
interface def : abc
{
void pqr();
}
Output
P19.cs(7,5): error CS0117: 'Demo' does not contain a definition for 'xyz'
P19.cs(8,5): error CS0117: 'Demo' does not contain a definition for 'pqr'
1 (oops)
2 (class)
3 (Class & Struct Diff..)
4 (object)
5 (Abstraction)
6 (Encapsulation)
7 (Encaps & Abst Diff..)
8 (Access Specifiers)
9 (specifiers in proper..)
10 (Object And Instance)
11 (pointers in C#)
12 (Inheritance)
13 (Why multi inheri...)
14 (Method Hiding)
15 (Polymorphism)
16 (Cohesion&Coupling)
17 (Coupling..)
18 (Constru & Dest..)
19 (Abst Class&method)
20(Interface)
21(Abst. Class & Int)
22(Use of abst and Int)
23(Static Class & Mem)
24(Aggregation,Asso...)
25(SOLID Principles)
21.Difference between Abstract Class and Interface
Feature
Interface
Abstract Class
Multiple inheritance
A class may inherit several interfaces.
A class may inherit only one abstract class.
Default implementation
An interface cannot provide any code, just the signature.
An abstract class can provide complete, default code and/or just the details that have to be overridden.
Access Modfiers
An interface cannot have access modifiers for the subs, functions, properties etc everything is assumed as public.
An abstract class can contain access modifiers for the subs, functions, properties.
Core VS Peripheral
Interfaces are used to define the peripheral abilities of a class. In other words both Human and Vehicle can inherit from a IMovable interface.
An abstract class defines the core identity of a class and there it is used for objects of the same type.
Homogeneity
If various implementations only share method signatures then it is better to use Interfaces.
If various implementations are of the same kind and use common behaviour or status then abstract class is better to use.
Speed
Requires more time to find the actual method in the corresponding classes.
Fast.
Adding functionality (Versioning)
If we add a new method to an Interface then we have to track down all the implementations of the interface and define implementation for the new method.
If we add a new method to an abstract class then we have the option of providing default implementation and therefore all the existing code might work properly.
Fields and Constants
No fields can be defined in interfaces.
An abstract class can have fields and constrants defined.
1 (oops)
2 (class)
3 (Class & Struct Diff..)
4 (object)
5 (Abstraction)
6 (Encapsulation)
7 (Encaps & Abst Diff..)
8 (Access Specifiers)
9 (specifiers in proper..)
10 (Object And Instance)
11 (pointers in C#)
12 (Inheritance)
13 (Why multi inheri...)
14 (Method Hiding)
15 (Polymorphism)
16 (Cohesion&Coupling)
17 (Coupling..)
18 (Constru & Dest..)
19 (Abst Class&method)
20(Interface)
21(Abst. Class & Int)
22(Use of abst and Int)
23(Static Class & Mem)
24(Aggregation,Asso...)
25(SOLID Principles)
22.Where to use Abstract Class and Where to use Interface?
Interface
–> If your child classes should all implement a certain group of methods/functionalities but each of the child classes is free to provide its own implementation then use interfaces.
For e.g. if you are implementing a class hierarchy for vehicles implement an interface called Vehicle which has properties like Colour MaxSpeed etc. and methods like Drive(). All child classes like Car Scooter AirPlane SolarCar etc. should derive from this base interface but provide a seperate implementation of the methods and properties exposed by Vehicle.
–> If you want your child classes to implement multiple unrelated functionalities in short multiple inheritance use interfaces.
For e.g. if you are implementing a class called SpaceShip that has to have functionalities from a Vehicle as well as that from a UFO then make both Vehicle and UFO as interfaces and then create a class SpaceShip that implements both Vehicle and UFO .
Abstract Classes
–> When you have a requirement where your base class should provide default implementation of certain methods whereas other methods should be open to being overridden by child classes use abstract classes.
For e.g. again take the example of the Vehicle class above. If we want all classes deriving from Vehicle to implement the Drive() method in a fixed way whereas the other methods can be overridden by child classes. In such a scenario we implement the Vehicle class as an abstract class with an implementation of Drive while leave the other methods / properties as abstract so they could be overridden by child classes.
–> The purpose of an abstract class is to provide a common definition of a base class that multiple derived classes can share.
For e.g. a class library may define an abstract class that is used as a parameter to many of its functions and require programmers using that library to provide their own implementation of the class by creating a derived class.
Use an abstract class
-When creating a class library which will be widely distributed or reused—especially to clients, use an abstract class in preference to an interface; because, it simplifies versioning. This is the practice used by the Microsoft team which developed the Base Class Library. ( COM was designed around interfaces.)
-Use an abstract class to define a common base class for a family of types.
-Use an abstract class to provide default behavior.
-Subclass only a base class in a hierarchy to which the class logically belongs.
Use an interface
-When creating a standalone project which can be changed at will, use an interface in preference to an abstract class; because, it offers more design flexibility.
-Use interfaces to introduce polymorphic behavior without subclassing and to model multiple inheritance—allowing a specific type to support numerous behaviors.
-Use an interface to design a polymorphic hierarchy for value types.
-Use an interface when an immutable contract is really intended.
-A well-designed interface defines a very specific range of functionality. Split up interfaces that contain unrelated functionality.
1 (oops)
2 (class)
3 (Class & Struct Diff..)
4 (object)
5 (Abstraction)
6 (Encapsulation)
7 (Encaps & Abst Diff..)
8 (Access Specifiers)
9 (specifiers in proper..)
10 (Object And Instance)
11 (pointers in C#)
12 (Inheritance)
13 (Why multi inheri...)
14 (Method Hiding)
15 (Polymorphism)
16 (Cohesion&Coupling)
17 (Coupling..)
18 (Constru & Dest..)
19 (Abst Class&method)
20(Interface)
21(Abst. Class & Int)
22(Use of abst and Int)
23(Static Class & Mem)
24(Aggregation,Asso...)
25(SOLID Principles)
23.Static Class and Static Class Members:
1.Static Class
The following list provides the main features of a static class:
•Contains only static and non-static members.
•Cannot be instantiated.
•Is sealed.
•Cannot contain Instance Constructors.
Note:
To create a non-static class that allows only one instance of itself to be created, Creating a static class is therefore basically the same as creating a class that contains only static members and a private constructor.
Static classes are sealed and therefore cannot be inherited. They cannot inherit from any class except Object. Static classes cannot contain an instance constructor; however, they can contain a static constructor.
2.Static Member
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. Static methods and properties cannot access non-static fields and events in their containing type, and they cannot access an instance variable of any object unless it is explicitly passed in a method parameter.
Static methods can be overloaded but not overridden.
Although a field cannot be declared as static const, a const field is essentially static in its behavior. It belongs to the type, not to instances of the type. Therefore, const fields can be accessed by using the same ClassName. MemberName notation that is used for static fields. No object instance is required.
C# does not support static local variables (variables that are declared in method scope).
Note:
If your class contains static fields, provide a static constructor that initializes them when the class is loaded.
1 (oops)
2 (class)
3 (Class & Struct Diff..)
4 (object)
5 (Abstraction)
6 (Encapsulation)
7 (Encaps & Abst Diff..)
8 (Access Specifiers)
9 (specifiers in proper..)
10 (Object And Instance)
11 (pointers in C#)
12 (Inheritance)
13 (Why multi inheri...)
14 (Method Hiding)
15 (Polymorphism)
16 (Cohesion&Coupling)
17 (Coupling..)
18 (Constru & Dest..)
19 (Abst Class&method)
20(Interface)
21(Abst. Class & Int)
22(Use of abst and Int)
23(Static Class & Mem)
24(Aggregation,Asso...)
25(SOLID Principles)
24.Aggregation, Association and Composition:
1.Association
It represents a relationship between two or more objects where all objects have their own lifecycle and there is no owner. The name of an association specifies the nature of relationship between objects. This is represented by a solid line.
Let’s take an example of relationship between Teacher and Student. Multiple students can associate with a single teacher and a single student can associate with multiple teachers. But there is no ownership between the objects and both have their own lifecycle. Both can be created and deleted independently.
2.Aggregation
It is a specialized form of Association where all object have their own lifecycle but there is ownership. This represents “whole-part or a-part-of” relationship. This is represented by a hollow diamond followed by a line.
Let’s take an example of relationship between Department and Teacher. A Teacher may belongs to multiple departments. Hence Teacher is a part of multiple departments. But if we delete a Department, Teacher Object will not destroy.
3.Composition
It is a specialized form of Aggregation. It is a strong type of Aggregation. In this relationship child objects does not have their lifecycle without Parent object. If a parent object is deleted, all its child objects will also be deleted. This represents “death” relationship. This is represented by a solid diamond followed by a line.
Let’s take an example of relationship between House and rooms. House can contain multiple rooms there is no independent life of room and any room cannot belongs to two different house if we delete the house room will automatically delete.
Let’s take another example of relationship between Questions and options. Single questions can have multiple options and option cannot belong to multiple questions. If we delete questions options will be automatically deleted.
1 (oops)
2 (class)
3 (Class & Struct Diff..)
4 (object)
5 (Abstraction)
6 (Encapsulation)
7 (Encaps & Abst Diff..)
8 (Access Specifiers)
9 (specifiers in proper..)
10 (Object And Instance)
11 (pointers in C#)
12 (Inheritance)
13 (Why multi inheri...)
14 (Method Hiding)
15 (Polymorphism)
16 (Cohesion&Coupling)
17 (Coupling..)
18 (Constru & Dest..)
19 (Abst Class&method)
20(Interface)
21(Abst. Class & Int)
22(Use of abst and Int)
23(Static Class & Mem)
24(Aggregation,Asso...)
25(SOLID Principles)
25.SOLID Principles
SOLID is an acronym and stands for 5 important object oriented principles.
1.Single Responsibility Principle
2.Open Closed Principle
3.Liskov Substitution Principle
4.Interface Segregation Principle
5.Dependency Inversion Principle
1.Single Responsibility Principle:
SRP states that every class should have a single responsibility, and that responsibility should be entirely encapsulated by the class. There should only be a single reason for making the change to a class.
It means that a class should not be loaded with multiple responsibilities and a single responsibility should not be scattered across multiple classes and mixed with other responsibilities. The reason is that the more changes requested in the future, the more changes the class needs to undergo.
Below is a code violating the SRP. In the sample code, SRP is violated by mixing the OpenGate and CloseGate responsibility with the core vehicle service functionality.
public class ServiceStation
{
public void OpenGate()
{
//Open the gate if the time is later than 9 AM
}
public void DoService(Vehicle vehicle)
{
//Check if service station is opened and then
//complete the vehicle service
}
public void CloseGate()
{
//Close the gate if the time has crossed 6PM
}
}
The re-factored code sample is as follows. A new interface is created and the gate related utility methods are moved to a different class called ServiceStationUtility.
public class ServiceStation
{
IGateUtility _gateUtility;
public ServiceStation(IGateUtility gateUtility)
{
this._gateUtility = gateUtility;
}
public void OpenForService()
{
_gateUtility.OpenGate();
}
public void DoService()
{
//Check if service station is opened and then
//complete the vehicle service
}
public void CloseForDay()
{
_gateUtility.CloseGate();
}
}
public class ServiceStationUtility : IGateUtility
{
public void OpenGate()
{
//Open the shop if the time is later than 9 AM
}
public void CloseGate()
{
//Close the shop if the time has crossed 6PM
}
}
public interface IGateUtility
{
void OpenGate();
void CloseGate();
}
2.Open Closed Principle (OCP):
OCP states that software application source codes should be open for extension but should be closed for modification.
Sometime modification on a code can create a problem if two or more client is accessing the same code. It is better to give extension for creating new method.
3.Liskov Substitution Principle (LSP)
LSP states that the derived classes should be perfectly substitutable for their base classes. If class D is derived from A then D should be substitutable for A.
Identify Problem in Programming
EXAMPLE: Normally when we talk about geometric shapes, we call a rectangle a base class for square. Let’s take a look at code snippet.
public class Rectangle
{
}
}
}
public class Square : Rectangle
{
//codes specific to
//square will be added
}
One can say,
Rectangle o = new Rectangle();
o.Width = 5;
o.Height = 6;
Perfect but as per LSP we should be able to replace Rectangle with square. Let’s try to do so.
Rectangle o = new Square();
o.Width = 5;
o.Height = 6;
What is the matter? Square cannot have different width and height.
What is the matter? Square cannot have different width and height.
Why don’t we make width and height virtual in Rectangle, and override them in Square?
Code snippet
public class Square : Rectangle
{
public override int Width
{
get
{
return base.Width;
}
set
{
base.Height = value;
base.Width = value;
}
}
public override int Height
{
get
{
return base.Height;
}
set
{
base.Height = value;
base.Width = value;
}
}
}
We can’t because doing so we are violating LSP, as we are changing the behavior of Width and Height properties in derived class (for Rectangle height and width cannot be equal, if they are equal it’s cannot be Rectangle).
(It will not be a kind of replacement).
Solution which will not violate LSP
There should be an abstract class Shape which looks like:
public class Square : Rectangle
{
public virtual intWidth { get; set; }
public virtual intHeight { get; set; }
}
Now there will be two concrete classes independent of each other, one rectangle and one square, both of which will be derived from Shape.
Now the developer can say:
Shape o = new Rectangle();
o.Width = 5;
o.Height = 6;
Shape o = new Square();
o.Width = 5; //both height and width become 5
o.Height = 6; //both height and width become 6
4.Interface Segregation principle (ISP)
ISP states that no clients should be forced to implement methods which it does not use and the contracts should be broken down to thin ones.
Say for example when a thick interface is defined declaring a wide responsibility of members then there will be opportunities where some clients may have to implement members, which they don’t even use. In the below mentioned example ISP is violated where ProcessCreditCard method is not required by InpersonOrder class but is forced to implement.
public interface IOrder
{
void Purchase();
void ProcessCreditCard();
}
public class OnlineOrder : IOrder
{
public void Purchase()
{
//Do purchase
}
public void ProcessCreditCard()
{
//process through credit card
}
}
public class InpersionOrder : IOrder
{
public void Purchase()
{
//Do purchase
}
public void ProcessCreditCard()
{
//Not required for inperson purchase
throw new NotImplementedException();
}
}
Now let us fix the violation by breaking down the IOrder interface.
public interface IOrder
{
void Purchase();
}
public interface IOnlineOrder
{
void ProcessCreditCard();
}
public class OnlineOrder : IOrder, IOnlineOrder
{
public void Purchase()
{
//Do purchase
}
public void ProcessCreditCard()
{
//process through credit card
}
}
public class InpersionOrder : IOrder
{
public void Purchase()
{
//Do purchase
}
}
5. Dependency Inversion Principle (DIP).
DIP states that the higher level modules should be coupled with the lower level modules with complete abstraction.
Dependency Injection Principle states that there should be more abstraction between the higher level module and the lower level module. It is required to have loose coupling so that any change in the low level modules will not affect or there will be minimal impact at the higher level module. The ideal scenario would be when you write components for other applications to consume.
Real World Comparison
Let’s talk about our desktop computers. Different parts such as RAM, a hard disk, and CD-ROM (etc.) are loosely connected to the motherboard. That means that, if, in future in any part stops working it can easily be replaced with a new one. Just imagine a situation where all parts were tightly coupled to each other, which means it would not be possible to remove any part from the motherboard. Then in that case if the RAM stops working we have to buy new motherboard which is going to be very expensive.
3 comments:
Good content , all at one place , specially for Indian market !
Informatics oops concepts at one place
This is pretty nice. very good stuff in here. i like it. it is helpful.
Post a Comment