Object-Oriented Programming

.Object-Oriented Programming
.Artic Fox

Inheritance | Polymorphism | Encapsulation

"Object-oriented programming is an approach to designing modular, reusable software systems."

Object-oriented programming (OOP) is a software development methodology which combines data (state) with code (behavior) into modular units called "objects". Objects, the foundational component of OOP, typically correspond to things found in the real world and are designed as class hierarchies (e.g. animal -> mammal -> carnivore -> canine -> Artic Fox). OOP allows for reusability and ease of maintenance through the use of three key concepts: inheritance, polymorphism, and encapsulation.

  • Inheritance is the ability to create new classes based on existing classes. Similar to genetic inheritance where certain traits are passed to children.

  • Polymorphism is the ability to have multiple classes that can be used interchangeably, even though each class implements the same properties or methods in different ways. That is, it allows interaction with a class as if it were it's base class. For example, we can use the Stream class as a parameter to a method, and then pass it either a FileStream, or a NetworkStream (as long as the method only accesses the capabilities of the base class).

  • Encapsulation is an object's ability to hide data and behavior that are not necessary to its user. Encapsulation enables a group of properties, methods and other members to be considered a single unit or object. Encapsulation can be viewed as the wall around your code which keeps people out ... but you can provide windows and doors so people can view or enter certain rooms.

Note: See the Polymorphism article for an in-depth review of the various types of polymorphism.

C# OOP Implementation Details

The implementation details of OOP varies among computer languages.The following describes details of OOP as implemented in the C# language:

  1. Everything in C# is derived from the Object class.

  2. C# implements inheritance in two ways:
    1. Class Inheritance - in C# a class can inherit only from a single base class (i.e. C# supports only a single base class).
    2. Interfaces - in C# a class may implement zero or more interfaces. An interface is a contract, or a promise, as to what a class is required to have in order for it to compile.

Inheritance

  • Inheritance enables you to create new classes that reuse, extend, and modify the behavior that is defined in other classes. The class whose members are inherited is called the base class, and the class that inherits those members is called the derived class. A derived class can have only one direct base class. However, inheritance is transitive. If ClassC is derived from ClassB, and ClassB is derived from ClassA, ClassC inherits the members declared in ClassB and ClassA.
  • Every class defaults from System.Object by default. So every object will have the System.Object methods like Equals and ToString.
  • Derived classes gain all the state and behavior of the base class.
  • Some languages, e.g., C++, allow Multiple inheritance, which allows a class to be derived from two or more classes, inheriting the members of all parents.
    C# and Java support single inheritance, meaning that a derived class can have only one parent class.
  • Below is a simple example of inheritance code. The abstract class can not be instantiated, it can only be used as a base class. The abstract method must be implemented in the derived classes:
.Example of Coding Inheritance

Inheritance Example

Animal.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace classExample
{
    // abstract base class
    public abstract class Animal
    {
        public string Name { get; set; }
        public string Noise { get; set; }
        // abstract method
        public abstract void MakeNoise();
    }

    class Dog : Animal
    {
        override public void MakeNoise()
        {
            Console.WriteLine("{0} says: {1}", Name, Noise);
        }
    }

    class Cat : Animal
    {
        override public void MakeNoise()
        {
            Console.WriteLine("{0} says: {1}", Name, Noise);
        }
    }

    class ScaredyCat : Cat
    {
        // Add a new property
        public string Action { get; set; }

        override public void MakeNoise()
        {
            Console.WriteLine("{0} says: {1} ... and then {2}.", Name, Noise, Action);
        }

        // Add a new method
        public void FindMe()
        {
            Console.WriteLine("{0} is hiding under the bed.", Name);
        }
    }

}


Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace classExample
{
    class Program
    {
        static void Main(string[] args)
        {
            Dog myDog = new Dog();
            myDog.Name = "Holly";
            myDog.Noise = "Feed me!";
            myDog.MakeNoise();
            Console.ReadLine();

            Cat myCat = new Cat();
            myCat.Name = "Shadow";
            myCat.Noise = "Pet me!";
            myCat.MakeNoise();
            Console.ReadLine();

            ScaredyCat myCat2 = new ScaredyCat();
            myCat2.Name = "Tessa";
            myCat2.Noise = "What was that!";
            myCat2.Action = "hides";
            myCat2.MakeNoise();
            Console.ReadLine();
            myCat2.FindMe();
            Console.ReadLine();
        }
    }

}




Polymorphism

  • Polymorphism is often referred to as the third pillar of object-oriented programming, after encapsulation and inheritance.
  • Polymorphism is the ability to assume different forms or shapes. The term Polymorphism comes from Greek, Poly meaning "many" and morph meaning "forms".
  • Polymorphism can be defined in two categories (static and dynamic). However some argue that static is really "Method Overloading" and is not considered to be polymorphism ... others claim it is. Some both categories are considered:

    1. Static Polymorphism aka. compile-time polymorphism, adhoc-polymorphism, method-overloading

    • Having the same method name but with different method signatures (number, type (int/float/string) and kind (value/reference) of parameters).
    • Methods can be overloaded with signatures that contain different numbers and/or different types, and/or different kinds of parameters.

    2. Dynamic Polymorphism aka. run-time polymorphism, type-polymorphism, method-overridding

    • Dynamic Polymorphism allows the invocation of derived class methods through a base class reference at run-time.
    • The base class method should be marked with the virtual keyword. If the derived class method is to be overridden, it must use the
    • override keyword.

    • 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.
    • 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.

.Static Polymorphism Program Output

Static Polymorphism (Method Overloading)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace staticPoly
{
    class Program
    {
        static void Main(string[] args)
        {
            Add(3, 7); // Call to 2 Integer Version
            Add(3, 7, 5); // Call to 3 Integer Version
            Add(3.3f, 7.4f); // Call to 2 Floating Point Version
            Add("Kevin ", "Harris"); // Call to 2 String Version
        }

        public static void Add(int val1, int val2)
        {
            Console.WriteLine("Two Sum = {0}", val1 + val2);
            Console.ReadLine();
        }

        public static void Add(int val1, int val2, int val3)
        {
            Console.WriteLine("Three Sum = {0}", val1 + val2 + val3);
            Console.ReadLine();
        }

        public static void Add(float val1, float val2)
        {
            Console.WriteLine("Float Sum = {0}", val1 + val2);
            Console.ReadLine();
        }

        public static void Add(string val1, string val2)
        {
            Console.WriteLine("String Concatenate = {0}", val1 + val2);
            Console.ReadLine();
        }
    }
}

.Dynamic Polymorphism Program Output


Dynamic Polymorphism (Method Overridding)

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DynamicPoly
{

    public class Animal
    {       
        public String Name { get; set; }

        public Animal()
        {
            Name = "Critter";
        }

        public virtual void WriteName()
        {
            Console.WriteLine("Name is: " + Name);
        }

    }

    public class Dog : Animal
    {
        public override void WriteName()
        {
            Console.WriteLine("Name is: " + Name + " - Dog");
        }
    }

    public class Cat : Animal
    {
        public override void WriteName()
        {
            Console.WriteLine("Name is: " + Name + " - Cat");
        }
    }

    public class Kitten : Cat
    {
        public override void WriteName()
        {
            Console.WriteLine("Name is: " + Name + " - Kitten");
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            // Array of base class elements
            Animal[] critters = new Animal[4];

            critters[0] = new Animal();
            critters[1] = new Dog();
            critters[1].Name = "Holly";
            critters[2] = new Cat();
            critters[2].Name = "Shadow";
            critters[3] = new Kitten();

            foreach (Animal a in critters)
            {
                a.WriteName();
            }
            Console.ReadLine();
        }
    }
}

Encapsulation

  • Encapsulation includes an information-hiding mechanism for restricting access to some of the object's components. Encapsulation hides the internal state of your object from direct access from outside code. This allows the internal implementation of the state to change at will, while presenting an interface that doesn't change. External code doesn't have access to the internal state of your object, so it can't alter it in an inconsistent manner that could break the way the object works.
  • C# offers the programmer a degree of control over what is hidden through the use of access modifiers. Access modifers are keywords in C# that declare the accessibility of a Class or a Class Member. The default access levels are:
    • class = internal
    • struct = internal
    • class members, struct members, nested classes and structs = private
    • interface members, enum members = always public (only)
    Keyword Applicable To Meaning
    public class, member Access is not restricted.
    protected member Access limited to the class and derived classes.
    internal class, member Access limited to the current assembly (.exe, .dll).
    protected internal member Access limited to current assembly and types derived from class.
    private member Access limited to the class.


Encapsulation Example

public : visible in MyData, MyHomeData, Main
protected : visible in MyData, MyHomeData
private : visible in MyData
.Access Modifier Example


Reference Articles

Top