none
C# - Interface vs Inheritance in specific example RRS feed

  • Question

  • Hello,

    I can has same behavior with interface and inheritance. Now what is difference between in this example between inheritance and interface and what is better now?

    using System;
    
    namespace ConsoleApp7
    {
        interface IHuman
        {
            void IBMI(int height, int weight);
        }
        abstract class Human
        {
            public virtual void BMI(int height, int weight) { }
            
        }
        class Student :Human , IHuman
        {
            public void IBMI(int h, int w)
            {
                Console.WriteLine(h * w); // Same BMI
            }
    
            public override void BMI(int h , int w)
            {
                Console.WriteLine(h*w); // Same IBMI
            }
        }
    }


    • Edited by Arash_89 Thursday, March 29, 2018 8:23 PM Add abstract keyword for better explain
    Thursday, March 29, 2018 7:41 PM

Answers

  • Greetings Arash.

    In your specific example, the Interface is completely unnecessary. The Student class will behave exactly the same with or without it. This is because a Student is a type of Human, so it makes sense that Student inherits all of Human's functionality.

    Generally, an Interface is for when one class is not a type of the other, but the classes have something in common. For example, a car is a type of vehicle and a bicycle is a type of vehicle, so the classes Car and Bicycle can both inherit from the Vehicle class. But a car is not a type of bicycle (or vice versa) so Car would not inherit from Bicycle. However, cars and bicycles both have wheels (they have something in common) so both could implement IWheel. Vehicles that do not have wheels (bobsleds, space ships, etc.) could inherit from Vehicle but not implement IWheel.

    • Marked as answer by Arash_89 Friday, March 30, 2018 12:25 AM
    Thursday, March 29, 2018 11:42 PM

All replies

  • I am not sure what you are asking here but the method IBMI is actually overridden in the Student class for IHuman  interface while BMI in Student class in overriden implementation for method in Human class.

    [If a post helps to resolve your issue, please click the "Mark as Answer" of that post or click Answered "Vote as helpful" button of that post. By marking a post as Answered or Helpful, you help others find the answer faster. ]


    Blog | LinkedIn | Stack Overflow | Facebook
    profile for Ehsan Sajjad on Stack Exchange, a network of free, community-driven Q&A sites

    Thursday, March 29, 2018 8:11 PM
  • Thank you, my question is: what is benefit for using interface? now i can use inheritance similar interface.( functionality for interface and inheritance is the same now)

    Thursday, March 29, 2018 8:22 PM
  • I can has same behavior with interface and inheritance. Now what is difference between in this example between inheritance and interface and what is better now?

    https://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)

    <copied>

    In object-oriented programming, inheritance is when an object or class is based on another object (prototypal inheritance) or class (class-based inheritance), using the same implementation.

    <end>

    You see inheritance in action where the basecontroller is inherited by a controller so that any exception that is thrown in a controller that inherits the basecontroller  is caught and logged in the basecontroller, which is called global exception handling. You even see Interfaces being used in the basecontroller.

    using System;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Routing;
    using log4net;
    
    namespace MVC.Controllers
    {
        public abstract partial class BaseController : Controller
        {
            private ILog _logger;
    
            protected BaseController()
            {
                _logger =  LogManager.GetLogger(typeof(BaseController));
            }
    
            protected override void OnException(ExceptionContext filterContext)
            {
                AppException appException = new AppException(Convert.ToString(filterContext.Exception))
                {
                    Type = filterContext.GetType().ToString(),
                    StackTrace = filterContext.Exception.StackTrace,
                    Source = filterContext.Exception.Source,
                    InnerException = Convert.ToString(filterContext.Exception.InnerException)
                };
    
                _logger.Error(appException.ToString());
    
                Server.ClearError();
    
                RedirectToControllers("Home", "Error");
            }
    
            private void RedirectToControllers(string control, string action)
            {
                var routeData = new RouteData();
    
                routeData.Values["controller"] = control;
    
                routeData.Values["action"] = action;
    
                IController controller = new HomeController();
    
                ((IController) controller).Execute(new RequestContext(
                    new HttpContextWrapper(System.Web.HttpContext.Current), routeData));
            }
        }
    }
    
    ---------------------------------------------
    
    using System;
    using System.Linq;
    using System.Web.Mvc;
    using MVC.Models;
    using Microsoft.AspNet.Identity;
    
    namespace MVC.Controllers
    {
        public class ProjectController : BaseController
        {
            // GET: Project
            [Authorize]
            public ActionResult Index()
            {
                return View(new ProjectModels().GetProjectsByUserId(User.Identity.GetUserId()));
            }
    
            [Authorize]
            public ActionResult Details(int id = 0)
            {
                return id == 0 ? null : View(new ProjectModels().Edit(id));
            }
    
            [Authorize]
            public ActionResult Create()
            {
                return View(new ProjectModels().Create());
            }
    
            [Authorize]
            [HttpPost]
            public ActionResult Create(ProjectViewModels.Project project, string submit)
            {
                if (submit == "Cancel") return RedirectToAction("Index");
    
                ValidateddlProjectTypes();
    
                project.ProjectType = (Request.Form["ddlProjectTypes"]);
    
                if (new ModelsHelper().IsEndDateLessThanStartDate(project, "Project"))
                    ModelState.AddModelError(string.Empty, "End Date cannot be less than Start Date.");
    
                if (!ModelState.IsValid) return View(new ProjectModels().PopulateSelectedList(project));
    
                new ProjectModels().Create(project, User.Identity.GetUserId());
                return RedirectToAction("Index");
            }
    
            [Authorize]
            public ActionResult Edit(int id = 0)
            {
                return id == 0 ? null : View(new ProjectModels().Edit(id));
            }
    
            [Authorize]
            [HttpPost]
            public ActionResult Edit(ProjectViewModels.Project project, string submit)
            {
                if (submit == "Cancel") return RedirectToAction("Index");
    
                if (new ModelsHelper().IsEndDateLessThanStartDate(project, "Project"))
                    ModelState.AddModelError(String.Empty, "End Date cannot be less than Start Date.");
    
                if (!ModelState.IsValid) return View(new ProjectModels().PopulateSelectedList(project));
    
                var theproject = new ProjectViewModels.Project();
    
                theproject = project;
    
                theproject.ProjectType = Request.Form["ProjectType"];
    
                new ProjectModels().Edit(theproject, User.Identity.GetUserId());
                return RedirectToAction("Index");
            }
    
            public ActionResult Delete(int id = 0)
            {
                if (id > 0) new ProjectModels().Delete(id);
    
                return RedirectToAction("Index");
            }
       
            public ActionResult Cancel()
            {
                return RedirectToAction("Index", "Home");
            }
    
            public ActionResult UploadFile(int id)
            {
                return RedirectToAction("UploadFile", "Upload", new { id = id, type = "PM" });
            }
    
            private void ValidateddlProjectTypes()
            {
                if (Request.Form["ddlProjectTypes"] == string.Empty)
                {
                    ModelState.AddModelError("ProjectType", "Project Type is required");
                }
                else
                {
                    foreach (var key in ModelState.Keys.ToList().Where(key => ModelState.ContainsKey(key)))
                    {
                        if (key == "ProjectType")
                            ModelState[key].Errors.Clear();
                    }
                }
            }
        }
    }
    

    https://www.cs.utah.edu/~germain/PPS/Topics/interfaces.html

    <copied>

    Interfaces in Object Oriented Programming Languages. An interface is a programming structure/syntax that allows the computer to enforce certain properties on an object (class).

    <end>

    In other words, an Interface enforces a contract between the called class/object and the calling class/object on the public properties and methods that can be seen by the calling class/object on the called class/object.

    You see the Interface in action for the class ProjectModels where the class must implement the method signatures defined by the IProjectModels.

    You see the ProjectController (code above) that calls the ProjectModels object only calling the methods as defined by the IProjectModels.

    namespace MVC.Models
    {
        public interface IProjectModels
        {
            ProjectViewModels GetProjectsByUserId(string userid);
            ProjectViewModels.Project GetProjectById(int id);
            ProjectViewModels.Project Create();
            void Create(ProjectViewModels.Project project, string userid);
            ProjectViewModels.Project Edit(int id);
            void Edit(ProjectViewModels.Project project, string userid);
            void Delete(int id);
            ProjectViewModels.Project PopulateSelectedList(ProjectViewModels.Project project);
        }
    }
    
    -----------------------------------------------
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.Mvc;
    using DAL;
    using Entities;
    
    
    namespace MVC.Models
    {
        public class ProjectModels : IProjectModels
        {
            public ProjectViewModels GetProjectsByUserId(string userid)
            {
                var vm = new ProjectViewModels {Projects = new List<ProjectViewModels.Project>()};
                
                var dtos = new DaoProject().GetProjectsByUserId(userid);
    
                vm.Projects.AddRange(dtos.Select(dto => new ProjectViewModels.Project()
                {
                    ProjectId = dto.ProjectId,
                    ClientName = dto.ClientName,
                    ProjectName = dto.ProjectName,
                    Technology = dto.Technology,
                    ProjectType = dto.ProjectType,
                    StartDate = dto.StartDate,
                    EndDate = dto.EndDate,
                    Cost = dto.Cost
                }).ToList());
    
                return vm;
            }
    
            public ProjectViewModels.Project GetProjectById(int id)
            {
                var dto = new DaoProject().GetProjectById(id);
    
                var project = new ProjectViewModels.Project
                { 
                    ProjectId = dto.ProjectId,
                    ClientName = dto.ClientName,
                    ProjectName = dto.ProjectName,
                    Technology = dto.Technology,
                    ProjectType = dto.ProjectType,
                    StartDate = dto.StartDate,
                    EndDate = dto.EndDate,
                    Cost = dto.Cost
                };
       
                return project;
            }
    
            public ProjectViewModels.Project Create()
            {
                var project = new ProjectViewModels.Project();
                return PopulateSelectedList(project);
            }
    
            public void Create(ProjectViewModels.Project project, string userid)
            {
                var dto = new DtoProject
                {
                    ProjectId = project.ProjectId,
                    ClientName = project.ClientName,
                    ProjectName = project.ProjectName,
                    ProjectType = project.ProjectType,  
                    Technology = project.Technology,
                    UserId = userid,
                    StartDate = (DateTime) project.StartDate,
                    EndDate = (DateTime) project.EndDate,
                    Cost = (decimal) project.Cost
                };
    
                new DaoProject().CreateProject(dto);
            }
    
            public ProjectViewModels.Project Edit(int id)
            {
                var dto = new DaoProject().GetProjectById(id);
    
                var project = new ProjectViewModels.Project
                { 
                    ProjectId = dto.ProjectId,
                    ClientName = dto.ClientName,
                    ProjectName = dto.ProjectName,
                    Technology = dto.Technology,
                    ProjectType = dto.ProjectType,
                    StartDate = dto.StartDate,
                    EndDate = dto.EndDate,
                    Cost = dto.Cost
                };
    
                project = PopulateSelectedList(project);
    
                return project;
            }
    
            public void Edit(ProjectViewModels.Project project, string userid)
            {
                var dto = new DtoProject
                {
                    ProjectId = project.ProjectId,
                    ClientName = project.ClientName,
                    ProjectName = project.ProjectName,
                    ProjectType = project.ProjectType,
                    Technology = project.Technology,
                    UserId = userid,
                    StartDate = (DateTime) project.StartDate,
                    EndDate = (DateTime) project.EndDate,
                    Cost = (decimal) project.Cost
                };
    
                new DaoProject().UpdateProject(dto);
            }
    
            public void Delete(int id)
            {
                new DaoProject().DeleteProject(id);
            }
    
            public ProjectViewModels.Project PopulateSelectedList(ProjectViewModels.Project project)
            {
                project.ProjectTypes = new List<SelectListItem>
                {
                    new SelectListItem {Value = "1", Text = "Fixed Price"},
                    new SelectListItem {Value = "2", Text = "Time & Material"}
                };
    
                var selected = (from a in project.ProjectTypes.Where(a => a.Value == project.ProjectType) select a)
                    .SingleOrDefault();
    
                if (selected != null)
                    selected.Selected = true;
    
                return project;
            }
        }
    }
    


    Thursday, March 29, 2018 9:27 PM
  • Greetings Arash.

    In your specific example, the Interface is completely unnecessary. The Student class will behave exactly the same with or without it. This is because a Student is a type of Human, so it makes sense that Student inherits all of Human's functionality.

    Generally, an Interface is for when one class is not a type of the other, but the classes have something in common. For example, a car is a type of vehicle and a bicycle is a type of vehicle, so the classes Car and Bicycle can both inherit from the Vehicle class. But a car is not a type of bicycle (or vice versa) so Car would not inherit from Bicycle. However, cars and bicycles both have wheels (they have something in common) so both could implement IWheel. Vehicles that do not have wheels (bobsleds, space ships, etc.) could inherit from Vehicle but not implement IWheel.

    • Marked as answer by Arash_89 Friday, March 30, 2018 12:25 AM
    Thursday, March 29, 2018 11:42 PM