Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Method overrides and polymorphysm

Tags:

c#

inheritance

I am trying to create a program that allows the user to check into a hotel room. The program should check if the room is free and then allocate one of the free rooms if any are available. I have multiple rooms types such as a single room, a double room, a twin room and so on which all need to inherit from the base class Room.

Here is my code currently.

public class Room 
{
    public static bool[] av = { false, true, false };

    public bool availability()
    {
        bool a = false;
        foreach (var roomAv in av)
        {
            a = a || roomAv;
        }
        return a;
    }

    public bool availability(int room)
    {
        return av[room];    
    }

    public int allocate()
    {
        if (availability())
        {
            int room = 0;
            while (!av[room])
            {
                room++;
            }
            av[room] = false;
            return room;
        }
        else
        {
            return -1;
        }
    }

    public static void roomStatus()
    {
        for (int i = 0; i < av.Length - 1; i++)
        {
            Console.WriteLine(i + av[i].ToString());
        }

    }
}

class SingleRoom
{

}

The functions I have defined in the room class need to be usable by all the different room types but each hold their own separate array stating whether they are available or not. How can I do this? How can I access those functions for each class but on there own separate array instead of performing them just on the 'av' array like I have currently.

like image 717
Adam Avatar asked Nov 24 '15 13:11

Adam


People also ask

What is difference between method overriding and polymorphism?

Overriding is when you call a method on an object and the method in the subclass with the same signature as the one in the superclass is called. Polymorphism is where you are not sure of the objects type at runtime and the most specific method is called.

What is the relationship between method overriding and polymorphism?

Method overriding is a run-time polymorphism. It helps to increase the readability of the program. It is used to grant the specific implementation of the method which is already provided by its parent class or superclass.

Is method overriding part of polymorphism?

Overriding is a form of polymorphism that is used in Java to dynamically bind the method from the subclass in response to a method call from a subclass object referenced by superclass type.

Is method overriding an example of polymorphism?

In case of method overloading, parameter must be different. In case of method overriding, parameter must be same. Method overloading is the example of compile time polymorphism. Method overriding is the example of run time polymorphism.


2 Answers

As you said you are new to C#, I would suggest to rethink on structure. You are in object-oriented paradigm. What you are thinking is plain old C-function oriented programming.

public class Room
{
    public bool IsAvailable {get; set;}
    public RoomType RoomType {get; set;}
    public int RoomNo {get; set;}
    public int Floor {get; set;}
    public string RoomName {get; set;}
}

public enum RoomType
{
     Single,
     Double,
     Twin,
     King,
     HoneymoonSuite
}

public class RoomManager
{
   public List<Room> AllRooms {get; set;}

   public RoomManager()
   {
       AllRooms = new List<Room>();

       AllRooms.Add(new Room(){ RoomType=RoomType.Single, 
                                RoomNo=1, 
                                Floor=1, 
                                RoomName="A101", 
                                IsAvailable=true});

       AllRooms.Add(new Room(){ RoomType=RoomType.Double, 
                                RoomNo=2, 
                                Floor=1, 
                                RoomName="A102", 
                                IsAvailable=false});

       AllRooms.Add(new Room(){ RoomType=RoomType.HoneyMoonSuite, 
                                RoomNo=1, 
                                Floor=2, 
                                RoomName="A201", 
                                IsAvailable=true});

      }

      public bool IsAvailable(int roomNo)
      {
          //You need to check if roomNo is a valid RoomNo
          return AllRooms.Any(r=>r.RoomNo==roomNo && r.IsAvailable);
      } 

      public bool IsAvailable(string roomName)
      {
          //You need to check if roomName is valid RoomName
          return AllRooms.Any(r=>r.RoomName==roomName && r.IsAvailable);
      }  

}
like image 113
Marshal Avatar answered Oct 14 '22 01:10

Marshal


The functions i have defined in the room class need to be usable by all the different room types but each hold their own separate array stating whether they are available or not. how can i do this?

When you use the static keyword for a variable, you're saying the variable belongs to the type itself instead of the object instance. Quoting from MSDN Docs:

Use the static modifier to declare a static member, which belongs to the type itself rather than to a specific object.

In other words, your array is "owned" by the class Room, not by individual objects of type Room created with new. If you want each object instance to own its own private member variables, then the static keyword needs to be removed. I.e.

public static bool[] av = { false, true, false };

should be:

public bool[] av = { false, true, false };

Note that the same applies to method names, i.e., if you use the static keyword on a method, the method is "owned" by the class/type itself, and not the individual object instances. This means, your roomStatus method must be used as Room.roomStatus() and trying new Room().roomStatus() would not be possible.

I'd actually recommend that you remove the array and turn this into a property, so that you can simply do something like:

Room r = new SingleRoom();
if(r.IsAvailable)
{
    // ...
}

You should also refactor your code to follow .NET naming conventions for your methods, variable names, and make better use of object-orientation. I think Niraj Doshi's post is a good step in that direction.

Since you're new to C#, I'd recommend you get a hold of the book Effective C# by B. Wagner.

Update - Refactored Code

This is my take on refactoring the code, having a RoomManager, a IRoom interface, an abstract implementation of the IRoom interface called Room with code and functionality common to all rooms, a concrete SingleRoom for a more specific type, and a TextView class to manage how the data will be presented/displayed to the user (i.e. text-based output).

Notice that this following the Model-View-Controller (MVC) design pattern, with the Room classes being the models (i.e. data), the TextView being responsible for displaying the data (i.e. presentation), and the Main program itself being the controller (i.e. coordinating the other two).

Main Program

The program simply adds some rooms and then displays information for each of them, based on the manager's capacity.

using System;
using System.Collections.Generic;

namespace HotelRoomManager
{
    class MainClass
    {
        public static void Main (string[] args)
        {
            RoomManager mgr = new RoomManager (5);
            for (uint i = 0; i < mgr.Capacity; ++i)
                mgr.AddRoom (new SingleRoom (1, i + 1) );

            List<IRoom> rooms = mgr.GetAllRooms ();
            TextView view = new TextView ();
            view.RenderHeader ();
            view.RenderModels (rooms);

            mgr.RemoveAllRooms ();
        }
    }
}

IRoom Interface

The interface defines a type and is the basis for all the rooms. Interfaces are used to define contracts with clients, and does not rely on implementation details, which makes it a good object-oriented practice.

using System;

namespace HotelRoomManager
{
    public enum BedType
    {
        Single,
        Double,
        Twin,
        Queen,
        King
    }

    public interface IRoom
    {
        BedType BedType { get; }
        uint Floor { get; }
        uint Number { get; }
        bool IsOccupied { get; set; }
    }
}

Abstract Room

The room simply contains code that is common to all rooms, regardless of their own individual details.

using System;

namespace HotelRoomManager
{
    public abstract class Room : IRoom
    {
        private uint floor;
        private uint number;
        private bool occupied;

        public Room (uint floor, uint number)
        {
            this.floor = floor;
            this.number = number;
            occupied = false;
        }

        public uint Floor {
            get { return floor; }
        }

        public uint Number {
            get { return number; }
        }

        public abstract BedType BedType { get; }

        public bool IsOccupied {
            get { return occupied; }
            set { occupied = value; }
        }

        override public string ToString() {
            return "Room(floor=" + floor + ", number=" + number + ")";
        }
    }
}

Concrete SingleRoom

By this point, this room only needs to report its actual type. It doesn't need to do anything special in addition to the common functionality already available.

using System;

namespace HotelRoomManager
{
    public sealed class SingleRoom : Room
    {
        public SingleRoom (uint floor, uint number) : base(floor, number)
        {}

        override public BedType BedType {
            get { return BedType.Single; }
        }
    }
}

The RoomManager

The manager simply helps to keep track of all the rooms and provides a simplified interface to interact with the collection.

using System;
using System.Collections.Generic;

namespace HotelRoomManager
{
    public class RoomManager
    {
        private List<IRoom> rooms;

        public RoomManager (uint capacity) {
            rooms = new List<IRoom> ();
            rooms.Capacity = (int) capacity;
        }

        public void AddRoom(IRoom room) {
            rooms.Add (room);
        }

        public void RemoveRoom(IRoom room) {
            rooms.Remove (room);
        }

        public List<IRoom> GetAllRooms() {
            return rooms;
        }

        public void RemoveAllRooms() {
            rooms.Clear ();
        }

        public uint Capacity {
            get { return (uint) rooms.Capacity; }
        }

    }
}

The TextView

The sole responsibility of the view is to decide how the data from the models will be presented to the user. This decouples the data itself from how the data is displayed, making your system easier to maintain and expand. You can also have multiple views available instead of having to choose between one or the other.

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

namespace HotelRoomManager
{
    public class TextView
    {
        public TextView () {}

        public void RenderHeader() {
            Console.WriteLine ("Hotel Management System");
            Console.WriteLine ("-----------------------");
        }

        public void RenderModels(List<IRoom> rooms) {
            StringBuilder sb = new StringBuilder ();
            foreach (IRoom r in rooms) {
                sb.Append ("Floor   : " + r.Floor + "\n");
                sb.Append ("Number  : " + r.Number + "\n");
                sb.Append ("Bed     : " + r.BedType + "\n");
                sb.Append ("Occupied: " + (r.IsOccupied ? "Yes" : "No") + "\n\n");
            }
            Console.WriteLine (sb.ToString ());
        }
    }
}

Output

A quick run of the program will produce the following output:

Hotel Management System
-----------------------
Floor   : 1
Number  : 1
Bed     : Single
Occupied: No

Floor   : 1
Number  : 2
Bed     : Single
Occupied: No

Floor   : 1
Number  : 3
Bed     : Single
Occupied: No

Floor   : 1
Number  : 4
Bed     : Single
Occupied: No

Floor   : 1
Number  : 5
Bed     : Single
Occupied: No
like image 43
code_dredd Avatar answered Oct 14 '22 00:10

code_dredd