Overclock.net › Forums › Software, Programming and Coding › Coding and Programming › Introduction to Interfaces in Object Oriented Programming
New Posts  All Forums:Forum Nav:

Introduction to Interfaces in Object Oriented Programming

post #1 of 5
Thread Starter 
Hey guys, I wrote up this document for some people at work and I figured I'd share it with the community. If people like this I will start writing more. I feel like there is lack of understanding with some key concepts in software architecture and object oriented programming and I hope to fill in some of those gaps for people. Just as a heads up if I were to continue writing these, the next one would cover the factory design pattern which relies on the use of interfaces.

Anyway, here's the write up. The code is in C# (that was my target audience initially) but if anyone wants this done in Java I can write up the sample code. Also my naming conventions don't adhere strictly to C# standards as when I wrote this I was still thinking in Java. My interface should be called IShape and the implementations can just be called, for example, ShapeRectangle or even Rectangle.



What is an interface and why is it important?

Object-Oriented Programming provides a number of useful features that allow a programmer to maintain clean, organized code that is easy to modify and extend.

Since this document is written with the intent to describe interfaces and why they are important, I will move directly to the point:

Interfaces provide a contract that every implementation must adhere to. They create a clear distinction between design and implementation while providing a framework that makes for simpler extension of code.

Let’s take a simple example. Suppose we have a shape. A shape can be any 2D shape like a circle, a rectangle, a triangle, etc. The point is any shape is a shape and there are things that all shapes have in common. For example, every shape has an area and some formula to obtain that area. Now, considering the aspects of object oriented programming, polymorphism should immediately come to mind. Polymorphism put simply, is the idea that an object can take more than one form, while still retaining the same behavior.

In the following examples, let’s assume that we are in a world only containing circles and rectangles. Let’s define the behavior of all shapes by saying that all shapes have a method to get their area and that all shapes have a method to draw themselves. First we will look at how we can do this, not using interfaces:


ShapeNoInterface.cs
Code:
class ShapeNoInterface
    {
        //For rectangles
        private float length;
        private float width;

        //For circles
        private float radius;

        private String type;

        public ShapeNoInterface(float radius)
        {
            this.type = "circle";
            this.radius = radius;
        }

        public ShapeNoInterface(float length, float width)
        {
            this.type = "rectangle";
            this.length = length;
            this.width = width;
        }

        public float getArea()
        {
            if (this.type.Equals("circle"))
            {
                return getCircleArea();
            }
            else if (this.type.Equals("rectangle"))
            {
                return getRectArea();
            }

            throw new InvalidOperationException("This shape doesn't exist!");
        }

        public void draw()
        {
            if (this.type.Equals("circle"))
            {
                drawCircle();
            }
            else if (this.type.Equals("rectangle"))
            {
                drawRectangle();
            }
            else
            {
                throw new InvalidOperationException("This shape doesn't exist!");
            }
        }

        private float getCircleArea()
        {
            return 2 * 3.14f * this.radius;
        }

        private float getRectArea()
        {
            return this.length * this.width;
        }

        private void drawCircle()
        {
            Console.WriteLine("This is a circle");
        }

        private void drawRectangle()
        {
            Console.WriteLine("This is a rectangle");
        }

    }


Not too bad, but a little cluttered. Now let’s look at the same code, but this time using interfaces.

First we define the interface (think of this as a design contract we must adhere to):

Shape.cs
Code:
    interface Shape
    {
        float getArea();
        void draw();
    }


Next we create our separate implementations (which must adhere to the above contract):

ShapeCircleImpl.cs
Code:
    class ShapeCircleImpl:Shape
    {
        private float radius;

        public ShapeCircleImpl(float radius)
        {
            this.radius = radius;
        }
        
        public float getArea()
        {
            return 2 * 3.14f * this.radius;
        }

        public void draw()
        {
            Console.WriteLine("This is a circle");
        }
    }

ShapeRectImpl.cs
Code:
class ShapeRectImpl:Shape
    {
        private float length;
        private float width;

        public ShapeRectImpl(float length, float width)
        {
            this.length = length;
            this.width = width;
        }

        public float getArea()
        {
            return this.length * this.width;
        }

        public void draw()
        {
            Console.WriteLine("This is a rectangle");
        }
    }

Immediately you should notice something. The amount of code used in the non-interface example is greater. The next thing you should notice is that the example using interfaces is much cleaner and easier to read. There is a clear separation of design and implementation.

Now let’s add another shape, triangles, to our code. First, no interfaces:

ShapeNoInterface.cs
Code:
class ShapeNoInterface
    {
        //For rectangles
        private float length;
        private float width;

        //For circles
        private float radius;

        //Added for triangles
        private float sideBase;
        private float sideHeight;
        private float sideHypotenuse;

        private String type;

        public ShapeNoInterface(float radius)
        {
            this.type = "circle";
            this.radius = radius;
        }

        public ShapeNoInterface(float length, float width)
        {
            this.type = "rectangle";
            this.length = length;
            this.width = width;
        }

        public ShapeNoInterface(float sideBase, float sideHeight, float sideHypotenuse)
        {
            this.type = "triangle";
            this.sideBase = sideBase;
            this.sideHeight = sideHeight;
            this.sideHypotenuse = sideHypotenuse;
        }

        public float getArea()
        {
            if (this.type.Equals("circle"))
            {
                return getCircleArea();
            }
            else if (this.type.Equals("rectangle"))
            {
                return getRectArea();
            }
            else if (this.type.Equals("triangle"))
            {
                return getTriangleArea();
            }

            throw new InvalidOperationException("This shape doesn't exist!");
        }

        public void draw()
        {
            if (this.type.Equals("circle"))
            {
                drawCircle();
            }
            else if (this.type.Equals("rectangle"))
            {
                drawRectangle();
            }
            else if (this.type.Equals("triangle"))
            {
                drawTriangle();
            }
            else
            {
                throw new InvalidOperationException("This shape doesn't exist!");
            }
        }

        private float getCircleArea()
        {
            return 2 * 3.14f * this.radius;
        }

        private float getRectArea()
        {
            return this.length * this.width;
        }

        private float getTriangleArea()
        {
            return .5f * (this.sideBase * this.sideHeight);
        }

        private void drawCircle()
        {
            Console.WriteLine("This is a circle");
        }

        private void drawRectangle()
        {
            Console.WriteLine("This is a rectangle");
        }

        private void drawTriangle()
        {
            Console.WriteLine("This is a triangle");
        }

    }

ShapeNoInterface is already beginning to become quite a mess. We had to add properties for a triangle, a constructor for a triangle, methods to calculate the area and draw, and finally add more “else if’s” to the getArea() and draw() methods. As you can see, this would become quite a task to add more and more shape implementations. This code is not only messy, if the caller is only ever going to use a circle, they are getting back an object containing all of the properties and methods for other shapes as well. Now let’s add a triangle to the code using interfaces. We simply define a triangle class that implements Shape:

ShapeTriangleImpl.cs
Code:
    class ShapeTriangleImpl:Shape
    {
        private float sideBase;
        private float sideHeight;
        private float sideHypotenuse;

        public ShapeTriangleImpl(float sideBase, float sideHeight, float sideHypotenuse)
        {
            this.sideBase = sideBase;
            this.sideHeight = sideHeight;
            this.sideHypotenuse = sideHypotenuse;
        }

        public float getArea()
        {
            return 0.5f * (sideBase * sideHeight);
        }

        public void draw()
        {
            Console.WriteLine("This is a triangle");
        }
    }

That’s it. By now, if you haven’t been using interfaces it should be easy to see why you should be using them. You not only have to write less code, your code is now much easier to read, understand, modify, and extend.

Below I will provide the code on how to use what we’ve covered. You will see that things don’t change much on the “client” side:

Program.cs
Code:
class Program
    {
        static void Main(string[] args)
        {
            //No interface
            //create circle
            ShapeNoInterface circle = new ShapeNoInterface(5f);

            //create rectangle
            ShapeNoInterface rect = new ShapeNoInterface(5f, 6f);

            //create triangle
            ShapeNoInterface triangle = new ShapeNoInterface(5f, 5f, 5f);

            //get area of one of the above
            Console.WriteLine(rect.getArea());
            Console.WriteLine(circle.getArea());
            Console.WriteLine(triangle.getArea());

            //draw one of the above
            circle.draw();
            rect.draw();
            triangle.draw();


            //interfaces
            //create circle
            Shape circle2 = new ShapeCircleImpl(5f);

            //create rectangle
            Shape rect2 = new ShapeRectImpl(5f, 6f);

            //create triangle
            Shape triangle2 = new ShapeTriangleImpl(5f, 5f, 5f);

            //get area of one of the above
            Console.WriteLine(rect2.getArea());
            Console.WriteLine(circle2.getArea());
            Console.WriteLine(triangle2.getArea());

            //draw one of the above
            circle2.draw();
            rect2.draw();
            triangle2.draw();

            Console.ReadLine();
        }
    }
post #2 of 5
Very nice write-up!

Really showcases the importance and advantages of Object-oriented programming and basically dividing your code into classes and objects for easier modification and extension of existing code. It should help people in understanding OOP.

thumb.gif
MacBook Pro 13"
(6 items)
 
 
Desktop
(13 items)
 
CPUGraphicsRAMHard Drive
Intel i5 3210 @ 2.5 GHz Intel HD4000 4 GB DDR3 @ 1600 MHz 500 GB @ 5400 RPM 
OSMonitor
OSX Mountain Lion 13.3" @ 1280 x 800 
CPUGraphicsRAMHard Drive
Intel i5 480m@2.67GHz AMD Radeon Mobility 5650 4GB DDR3 500GB 
OSMonitor
Windows 7 64bit HP 15.6" 1366x768 
CPUMotherboardGraphicsRAM
E7500 Intel...:( MSI GTS250 1GB 2GB 
Hard DriveOSMonitorPower
250GB Windows XP 17" LG CRT 1280x768@85hz 400W 
  hide details  
Reply
MacBook Pro 13"
(6 items)
 
 
Desktop
(13 items)
 
CPUGraphicsRAMHard Drive
Intel i5 3210 @ 2.5 GHz Intel HD4000 4 GB DDR3 @ 1600 MHz 500 GB @ 5400 RPM 
OSMonitor
OSX Mountain Lion 13.3" @ 1280 x 800 
CPUGraphicsRAMHard Drive
Intel i5 480m@2.67GHz AMD Radeon Mobility 5650 4GB DDR3 500GB 
OSMonitor
Windows 7 64bit HP 15.6" 1366x768 
CPUMotherboardGraphicsRAM
E7500 Intel...:( MSI GTS250 1GB 2GB 
Hard DriveOSMonitorPower
250GB Windows XP 17" LG CRT 1280x768@85hz 400W 
  hide details  
Reply
post #3 of 5
Excellent! I know that when I first started learning OOP, interfacing my classes was one of the harder concepts for me to get used to (although now it just seems like common sense to use them). This is very comprehensive and should be a lot of help for beginners. Great work.
Viking
(13 items)
 
  
CPUMotherboardGraphicsRAM
Intel Core i5 2500K @ 4.8 GHz 1.45V P8Z68-V GEN3 [2x] EVGA GeForce GTX 570 SLI [2x] Kingston HyperX 4GB 1600MHz 
Hard DriveHard DriveCoolingCooling
Crucial M4 128GB [2x] WD 320GB XSPC Single Bay Reservoir Swiftech MCP655 
CoolingCoolingOSPower
XSPC Raystorm XSPC EX240 Windows 7 Pro 64-bit Corsair HX850 
Case
Corsair Obsidian 650D 
  hide details  
Reply
Viking
(13 items)
 
  
CPUMotherboardGraphicsRAM
Intel Core i5 2500K @ 4.8 GHz 1.45V P8Z68-V GEN3 [2x] EVGA GeForce GTX 570 SLI [2x] Kingston HyperX 4GB 1600MHz 
Hard DriveHard DriveCoolingCooling
Crucial M4 128GB [2x] WD 320GB XSPC Single Bay Reservoir Swiftech MCP655 
CoolingCoolingOSPower
XSPC Raystorm XSPC EX240 Windows 7 Pro 64-bit Corsair HX850 
Case
Corsair Obsidian 650D 
  hide details  
Reply
post #4 of 5
Same for me but since i got the OOP design pattern course and refactoring it become way more easier for me. I made a 115 pages document with all the design patterns and their uses and all the refactoring techniques and their uses but its in french if you guys want it i can send it to you and just use google translator to translate my word document:thumb:
inspek
(16 items)
 
  
CPUMotherboardGraphicsRAM
i7 2700k  Asus P8Z68-V GEN3 EVGA GTX480 1536mb G Skill F3-14900 2 x 4gb 1866mhz 
Hard DriveHard DriveOptical DriveCooling
WD Caviar Black 1Tb Kingston Hyper X 120Gb SSD LG 24x dvd multi Corsair H60 push/pull set up 
OSMonitorKeyboardPower
Windows 7 professionnal X64 Samsung Suncmaster 2253lw 2ms Logitech G15 Antec High current pro 1200w 
CaseMouseAudioOther
CoolerMaster HAF-X Logitech G500 Logitech X-530 Dlink DGL-4500 router gamerlounge  
  hide details  
Reply
inspek
(16 items)
 
  
CPUMotherboardGraphicsRAM
i7 2700k  Asus P8Z68-V GEN3 EVGA GTX480 1536mb G Skill F3-14900 2 x 4gb 1866mhz 
Hard DriveHard DriveOptical DriveCooling
WD Caviar Black 1Tb Kingston Hyper X 120Gb SSD LG 24x dvd multi Corsair H60 push/pull set up 
OSMonitorKeyboardPower
Windows 7 professionnal X64 Samsung Suncmaster 2253lw 2ms Logitech G15 Antec High current pro 1200w 
CaseMouseAudioOther
CoolerMaster HAF-X Logitech G500 Logitech X-530 Dlink DGL-4500 router gamerlounge  
  hide details  
Reply
post #5 of 5
Great guide
    
CPUMotherboardGraphicsGraphics
Intel Core i7 860 Asus P7P55D-E Pro MSI GTX560 Ti TwinFrozr II MSI GTX560 Ti TwinFrozr II 
RAMHard DriveHard DriveHard Drive
Corsair 8GB DDR3 OCZ Vertex 3 Western Digital Caviar Black Western Digital Caviar Green 
Hard DriveOptical DriveCoolingOS
Samsung 840 Pro Lite-On 24x DVD-RW CoolerMaster V8 Windows 8.1 Professional 
OSMonitorMonitorMonitor
Debian 7.1 Samsung S22B350H Samsung S22B350H Samsung S22B350H 
KeyboardPowerCaseMouse
Ducky Shine II Corsair HX850 CoolerMaster Storm Enforcer Logitech M500 
Mouse PadAudio
Razer Goliathus Microsoft LifeChat LX 3000 
  hide details  
Reply
    
CPUMotherboardGraphicsGraphics
Intel Core i7 860 Asus P7P55D-E Pro MSI GTX560 Ti TwinFrozr II MSI GTX560 Ti TwinFrozr II 
RAMHard DriveHard DriveHard Drive
Corsair 8GB DDR3 OCZ Vertex 3 Western Digital Caviar Black Western Digital Caviar Green 
Hard DriveOptical DriveCoolingOS
Samsung 840 Pro Lite-On 24x DVD-RW CoolerMaster V8 Windows 8.1 Professional 
OSMonitorMonitorMonitor
Debian 7.1 Samsung S22B350H Samsung S22B350H Samsung S22B350H 
KeyboardPowerCaseMouse
Ducky Shine II Corsair HX850 CoolerMaster Storm Enforcer Logitech M500 
Mouse PadAudio
Razer Goliathus Microsoft LifeChat LX 3000 
  hide details  
Reply
New Posts  All Forums:Forum Nav:
  Return Home
  Back to Forum: Coding and Programming
Overclock.net › Forums › Software, Programming and Coding › Coding and Programming › Introduction to Interfaces in Object Oriented Programming