Thread: Polymorphism and generic lists

  1. #1
    Registered User
    Join Date
    Jul 2010
    Posts
    4

    Polymorphism and generic lists

    Hey guys, I'm trying to make an application for vehicles in inventory. Well i'm using a generic list and have a class of Vehicle, of which a vehicle type like Car, Truck and SUV will inherit from, so far I've created a Car class. Now thats what Im having trouble with. From my understanding I need to do something along the lines of
    Vehicle myVehicle;
    myVehicle = new Car(); or
    myVehicle = new Truck(); etc..

    The cartype like Car will have specific attributes like being a v4, having 4 doors, and having say 4 passangers. A truck would have attributes like being a v8, 2 doors, 3 passangers, and well you get the idea.

    The way i have the code set up below, I don't believe the Car class is inheriting the info that needs to because when I run it, I get all the "None" from the Car class as an output on the listBox - which is where only multiple entries with the same information should appear. So I am seeking some guidance as to how I could make each Vehicle type inherit the information properly for each vehicle type,and add more info to it (which the user will input as well) like the engine, # of doors and passengers and then display it.
    I hope was clear enough...
    Thanks in advance for any help.

    Code:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Collections;
    using System.IO;
    
    namespace Inventory
    {
        public partial class Form1 : Form
        {
            public string output;
            public string vtype;
           // ArrayList VehicleCollection = new ArrayList();
            List<Vehicle> VehicleCollection = new List<Vehicle>();
            Vehicle myVehicle;
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void btnAdd_Click(object sender, EventArgs e)
            {
                try{
                long num = Convert.ToInt64(txtStockNumber.Text);
                if (txtStockNumber.Text == "")
                {
                    MessageBox.Show("Please enter all of the data for the Vehicle");
                    txtStockNumber.Focus();
                }
                else if (txtYear.Text == "")
                {
                    MessageBox.Show("Please enter all of the data for the Vehicle");
                    txtYear.Focus();
                }
                else if (txtMake.Text == "")
                {
                    MessageBox.Show("Please enter all of the data for the Vehicle");
                    txtMake.Focus();
                }
                else if (txtModel.Text == "")
                {
                    MessageBox.Show("Please enter all of the data for the Vehicle");
                    txtModel.Focus();
                }
    
                else if((rdoCar.Checked == false) && (rdoTruck.Checked == false) && (rdoSUV.Checked == false) && (rdoCrossover.Checked==false))
                {
                    MessageBox.Show("Please select a vehicle type");
                }
                else if (txtMSRP.Text == "")
                {
                    MessageBox.Show("Please enter all of the data for the Vehicle");
                    txtMSRP.Focus();
                }
                else if ((num < 10000) || (num > 99999))
                {
                    MessageBox.Show("Please Enter 5 Numbers for the Stock Number");
                }
       
                else
                {
                    myVehicle = new Car();
                    
    
                    myVehicle.StockNumber = txtStockNumber.Text;
                    myVehicle.Year = txtYear.Text;
                    myVehicle.Make = txtMake.Text;
                    myVehicle.Model = txtModel.Text;
                    myVehicle.VehicleType = vtype;
                    myVehicle.MSRP = txtMSRP.Text;
    
                    MessageBox.Show("Vehicle Added");
                    txtStockNumber.Text = "";
                    txtYear.Text = "";
                    txtMake.Text = "";
                    txtModel.Text = "";
                    txtMSRP.Text = "";
                    
                    rdoCar.Checked = false;
                    rdoTruck.Checked = false;
                    rdoSUV.Checked = false;
                    rdoCrossover.Checked = false;
                    listList.Items.Clear();
                    VehicleCollection.Add(myVehicle);
    
    
                }
                }//ends try
                catch(OverflowException)
                {
                    MessageBox.Show("Please Enter 5 Numbers for the Stock Number");
                }
    
            
            }
    
            private void btnFind_Click(object sender, EventArgs e)
            {
                string stockNumber = txtStockNumber.Text;
                string year = txtYear.Text;
                string make = txtMake.Text;
                string model = txtModel.Text;
                stockNumber = stockNumber.Trim();
                year = year.Trim();
                make = make.Trim();
                model = model.Trim();
                
                Vehicle vehic = new Car();
    
                if (stockNumber != "" || year != "" || (make != "" && model != ""))
                {
                    for (int i = 0; i < VehicleCollection.Count; i++)
                    {
                        vehic = (Vehicle)VehicleCollection[i];
                        if ((vehic.StockNumber.ToUpper()).Equals(stockNumber.ToUpper()))
                        {
                            txtYear.Text = vehic.Year;
                            txtMake.Text = vehic.Make;
                            txtModel.Text = vehic.Model;
                            vtype = vehic.VehicleType;
                            txtMSRP.Text = vehic.MSRP;
                            if (vtype == "CAR")
                            {
                                rdoCar.Checked = true;
                            }
                            else if (vtype == "TRUCK")
                            {
                                rdoTruck.Checked = true;
                            }
                            else if (vtype == "SUV")
                            {
                                rdoSUV.Checked = true;
                            }
                            else if (vtype == "CROSSOVER")
                            {
                                rdoCrossover.Checked = true;
                            }
                           
                            listList.Items.Clear();
                            int listCounter = 0;
                            for (int j = 0; j < VehicleCollection.Count; j++)
                            {
                                
                                vehic = (Vehicle)VehicleCollection[j];
                                if ((vehic.StockNumber.ToUpper()).Equals(stockNumber.ToUpper()))
                                {
                                    listList.Items.Add(vehic.ToString());
                                    listCounter++;
                                }
                            }
                            if (listCounter > 1)
                            {
                                txtStockNumber.Text = "";
                                txtYear.Text = "";
                                txtMake.Text = "";
                                txtModel.Text = "";
                                txtMSRP.Text = "";
                              
                                rdoCar.Checked = false;
                                rdoTruck.Checked = false;
                                rdoSUV.Checked = false;
                                rdoCrossover.Checked = false;
    
                            }
                            else
                            {
                                listList.Items.Clear();
                            }
                            break;
                        }
                        else if ((vehic.Year.ToUpper()).Equals(year.ToUpper()))
                        {
                            txtStockNumber.Text = vehic.StockNumber;
                            txtMake.Text = vehic.Make;
                            txtModel.Text = vehic.Model;
                           
                            txtMSRP.Text = vehic.MSRP;
                            
                            vtype = vehic.VehicleType;
                            listList.Items.Clear();
                            int listCounter = 0;
                            for (int j = 0; j < VehicleCollection.Count; j++)
                            {
    
                                vehic = (Vehicle)VehicleCollection[j];
                                if ((vehic.Year.ToUpper()).Equals(year.ToUpper()))
                                {
                                    listList.Items.Add(vehic.ToString());
                                    listCounter++;
                                }
                            }
                            if (listCounter > 1)
                            {
                                txtStockNumber.Text = "";
                                txtYear.Text = "";
                                txtMake.Text = "";
                                txtModel.Text = "";
                                txtMSRP.Text = "";
                                
                                rdoCar.Checked = false;
                                rdoTruck.Checked = false;
                                rdoSUV.Checked = false;
                                rdoCrossover.Checked = false;
                            }
                            else
                            {
                                listList.Items.Clear();
                            }
                            break;
                        }
                        else if ((vehic.Make.ToUpper()).Equals(make.ToUpper()) && (vehic.Model.ToUpper().Equals(model.ToUpper())))
                        {
                            txtStockNumber.Text = vehic.StockNumber;
                            txtYear.Text = vehic.Year;
                            
                            txtMSRP.Text = vehic.MSRP;
                            vtype = vehic.VehicleType;
    
                            listList.Items.Clear();
                            int listCounter = 0;
                            for (int j = 0; j < VehicleCollection.Count; j++)
                            {
    
                                vehic = (Vehicle)VehicleCollection[j];
                                if ((vehic.Make.ToUpper()).Equals(make.ToUpper()) && (vehic.Model.ToUpper().Equals(model.ToUpper())))
                                {
                                    listList.Items.Add(vehic.ToString());
                                    listCounter++;
                                }
    
                            }//ends for loop
                            // found = true;
                            if (listCounter > 1)
                            {
                                txtStockNumber.Text = "";
                                txtYear.Text = "";
                                txtMake.Text = "";
                                txtModel.Text = "";
                                txtMSRP.Text = "";
                            
                                rdoCar.Checked = false;
                                rdoTruck.Checked = false;
                                rdoSUV.Checked = false;
                                rdoCrossover.Checked = false;
                            }
                            else
                            {
                                listList.Items.Clear();
                            }
                            break;
                        }
                      
                    } //ends loop
                }///ends if
    
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
    
            }
    
            private void btnDelete_Click(object sender, EventArgs e)
            {
                string stockNumber = txtStockNumber.Text;
                stockNumber = stockNumber.Trim();
    
               
    
                if (stockNumber != "")
                {
                    foreach (Vehicle vehicle1 in VehicleCollection)
                    {
                        if ((vehicle1.StockNumber.ToUpper()).Equals(stockNumber.ToUpper()))
                        {
                            VehicleCollection.Remove(vehicle1);
                        
                            break;
                        }
    
    
                    }//end foreach
                    MessageBox.Show("Vehicle Deleted");
                    txtStockNumber.Text = "";
                    txtYear.Text = "";
                    txtMake.Text = "";
                    txtModel.Text = "";
                    txtMSRP.Text = "";
                  
                    rdoCar.Checked = false;
                    rdoTruck.Checked = false;
                    rdoSUV.Checked = false;
                    rdoCrossover.Checked = false;
    
                    listList.Items.Clear();
    
                }
            }
    
            private void btnSaveChanges_Click(object sender, EventArgs e)
            {
                bool found = false;
                String stockNumber = txtStockNumber.Text.Trim();
    
                if (stockNumber != "")
                {
                    foreach (Vehicle vehicle2 in VehicleCollection)
                    {
                        if ((vehicle2.StockNumber.ToUpper()).Equals(stockNumber.ToUpper()))
                        {
                            vehicle2.Year = txtYear.Text.Trim();
                            vehicle2.Make = txtMake.Text.Trim();
                            vehicle2.Model = txtModel.Text.Trim();
                           
                            vehicle2.MSRP = txtMSRP.Text.Trim();
                            vehicle2.VehicleType = vtype.Trim();
    
                            MessageBox.Show("Changes Saved");
                            found = true;
                            break;
                        }
                        
                    } //ends foreach
                } //ends if
    
                if (!found)
                {
                    MessageBox.Show("Can not find Vehicle entered");
                }
    
                object o = new object();
                EventArgs ea = new EventArgs();
               
                txtStockNumber.Text = "";
                txtYear.Text = "";
                txtMake.Text = "";
                txtModel.Text = "";
                txtMSRP.Text = "";
              
                rdoCar.Checked = false;
                rdoTruck.Checked = false;
                rdoSUV.Checked = false;
                rdoCrossover.Checked = false;
                listList.Items.Clear();
            }
    
            private void btnSaveToFile_Click(object sender, EventArgs e)
            {      
                String stockNumber = txtStockNumber.Text.Trim();
    
    
                Vehicle ve = new Car();
    
    
                if (stockNumber != "")
                {
    
                    foreach (Vehicle vehicle2 in VehicleCollection)
                    {
    
                        if (vehicle2.StockNumber.ToUpper().Equals(stockNumber.ToUpper()))
                        {
    
                            vehicle2.Year = txtYear.Text.Trim();
                            vehicle2.Make = txtMake.Text.Trim();
                            vehicle2.Model = txtModel.Text.Trim();
                            
                            vehicle2.MSRP = txtMSRP.Text.Trim();
                            vehicle2.VehicleType = vtype.Trim();
    
    
                           
    
                            break;
                        }
    
                    } //ends foreach
                } //ends if
    
               
            
         
    
                string line = "";
    
                for (int i = 0; i < VehicleCollection.Count; ++i)
                {
                    line += VehicleCollection[i].ToString() + "@";
                }
    
                string[] values = line.Split(new char[] { '@' });
    
                System.IO.File.WriteAllLines(@"C:\Projects\vehicles.txt", values);
    
                MessageBox.Show("Saved");
            }
    
            private void rdoCar_CheckedChanged(object sender, EventArgs e)
            {
                txtTrunkSpace.ReadOnly = false;
                txtTowing.ReadOnly = true;
                txtStorage.ReadOnly = true;
                vtype = "CAR";
            }
    
            private void rdoTruck_CheckedChanged(object sender, EventArgs e)
            {
                txtStorage.ReadOnly = true;
                txtTrunkSpace.ReadOnly = true;
                txtTowing.ReadOnly = false;
                vtype = "TRUCK";
            }
    
            private void rdoSUV_CheckedChanged(object sender, EventArgs e)
            {
                txtTrunkSpace.ReadOnly = true;
                txtTowing.ReadOnly = true;
                txtStorage.ReadOnly = false;
                vtype = "SUV";
            }
    
            private void rdoCrossover_CheckedChanged(object sender, EventArgs e)
            {
                txtTrunkSpace.ReadOnly = true;
                txtTowing.ReadOnly = true;
                txtStorage.ReadOnly = false;
                vtype = "CROSSOVER";
            }
            
            }//ends form class
         public abstract class Vehicle
        {
            private string stockNumber;
            private string year;
            private string make;
            private string model;
            private string vehicleType;
            private string msrp;
    
            public override string ToString()
            {
                return (stockNumber + "-" + year + "-" + make + "-" + model + "-" + vehicleType + "-" + msrp + System.Environment.NewLine);
            }
    
            public Vehicle(string s, string yr, string ma, string mo, string vt, string mp)
            {
                stockNumber = s;
                year = yr;
                make = ma;
                model = mo;
                vehicleType = vt;
                msrp = mp;
            }
    
            public Vehicle()
            {
                stockNumber = "None";
                year = "None";
                make = "None";
                model = "None";
                vehicleType = "None";
                msrp = "None";
            }
    
            public string StockNumber
            {
                get
                {
                    return stockNumber;
                }
                set
                {
                    stockNumber = value;
                }
            }
    
            public string Year
            {
                get
                {
                    return year;
                }
                set
                {
                    year = value;
                }
            }
            public string Make
            {
                get
                {
                    return make;
                }
                set
                {
                    make = value;
                }
            }
            public string Model
            {
                get
                {
                    return model;
                }
                set
                {
                    model = value;
                }
            }
            public string VehicleType
            {
                get
                {
                    return vehicleType;
                }
                set
                {
                    vehicleType = value;
                }
            }
            public string MSRP
            {
                get
                {
                    return msrp;
                }
                set
                {
                    msrp = value;
                }
            }
        } //ends Vehicle class
    
    }
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Inventory
    {
        class Car : Vehicle
        {
            public string StockNumber { get; set; }
            public string Year { get; set; }
            public string Make { get; set; }
            public string Model { get; set; }
            public string MSRP { get; set; }
    
            public Car(string s, string yr, string ma, string mo, string mp)// : base(s, yr, ma, mo, mp)
            {
                StockNumber = s;
                Year = yr;
                Make = ma;
                Model = mo;
                // vehicleType = vt;
                MSRP = mp;
            }
            public Car()
            {
                StockNumber = "0";
                Year = "None";
                Make = "None";
                Model = "None";
                // vehicleType = "None";
                MSRP = "None";
            }
    
            public override string ToString()
            {
                return (StockNumber + "-" + Year + "-" + Make + "-" + Model + "-" + "CAR" + "-" + MSRP + System.Environment.NewLine);
            }
        }
    }

  2. #2
    Anti-Poster
    Join Date
    Feb 2002
    Posts
    1,401
    I can't say for sure, but I believe the problem is that you're defining the properties in both Vehicle and Car. Because they are not virtual and they have the same name, the Car properties are hiding the Vehicle properties. Try taking the properties out of your Car class.

    Why exactly do you need a Car class and a Truck class? Notice that you didn't add any additional properties to Car that Vehicle didn't already have.
    If I did your homework for you, then you might pass your class without learning how to write a program like this. Then you might graduate and get your degree without learning how to write a program like this. You might become a professional programmer without knowing how to write a program like this. Someday you might work on a project with me without knowing how to write a program like this. Then I would have to do you serious bodily harm. - Jack Klein

  3. #3
    Registered User
    Join Date
    Jul 2010
    Posts
    4

    Yea

    Your right, thanks for the help. I will add additional information like the engine type of v4 or v6, and having either 2 doors or 4 doors. I was wondering if it was possible for the user to enter the information and be added to the Car class/Truck class without it being a part of the Vehicle class, since as you implied - car needs to have additional properties over vehicle. But im thinking this cannot be done. In which case i need to hardcode the additional information into the car/truck classes, correct?

  4. #4
    Registered User
    Join Date
    Jun 2003
    Posts
    129
    You wouldn't really need to inherit so much. Have an int/whatever for the number of doors etc. If the user has to enter everything anyway, you're just adding extra code by inheriting.

    Example, you have 2 cars, one a saloon, one a sports car. 4 seats in one, 2 in the other, inline 4 in the saloon, v8 in the sports. Having inherited classes, the user would have to select the vehicle type, then the additional information, more keypresses or mouse clicks = bad in user interfacing. It would be simple to code something that can classify an object between two or more types in this way, not many 4 seat sports cars out there, and it's definitely not a saloon with 2 seats!
    He who asks is a fool for five minutes, but he who does not ask remains a fool forever.

    The fool wonders, the wise man asks. - Benjamin Disraeli

    There are no foolish questions and no man becomes a fool until he has stopped asking questions. Charles Steinmetz

  5. #5
    Anti-Poster
    Join Date
    Feb 2002
    Posts
    1,401
    It is possible for each derived class to have additional information that it does not share with the base class; indeed, most derived classes do. However, I don't think you really need inheritance here.

    For example, you keep saying that additional information will be things like an engine type and the number of doors. Both Cars and Trucks have engine types and door counts, so if those are your only expected derived types of Vehicle, then those properties should go on Vehicle. If you were planning to derive a type that didn't have one of those (for example, a Bicycle type), then the property that wasn't shared would go on the derived types.

    For example, let's say you wanted to add a Bicycle type. You might be able to stretch Engine Type and say that a Bicycle uses a human engine. And you might say that a Bicycle has a Door Count; it simply has zero doors. If you did it that way, it would be fine for Vehicle to have both of those properties since they would be shared with all expected derived classes. However, it might be more intuitive to not have those properties on Bicycle. In that case, both Car and Truck would have those properties instead of the base class Vehicle.

    An easy test to see if you need inheritance: describe a single property that your program will use that a Car has that a Truck does not have or vice versa. If there is no such property, then you don't need inheritance.
    Having inherited classes, the user would have to select the vehicle type, then the additional information, more keypresses or mouse clicks = bad in user interfacing.
    That inherited classes were used shouldn't be represented in the user interface. You could have just as poor a user interface without inherited classes, and you could have a better user interface with inherited classes. The internal structure of the code should not dictate user interface design.
    If I did your homework for you, then you might pass your class without learning how to write a program like this. Then you might graduate and get your degree without learning how to write a program like this. You might become a professional programmer without knowing how to write a program like this. Someday you might work on a project with me without knowing how to write a program like this. Then I would have to do you serious bodily harm. - Jack Klein

  6. #6
    Registered User
    Join Date
    Jul 2010
    Posts
    4

    =]

    exactly, i never saw the need for the inheritance either. but it turns out thats just how the prof wants it. but thanks for the help.

  7. #7
    Anti-Poster
    Join Date
    Feb 2002
    Posts
    1,401
    That's a terrible example problem to teach inheritance, since it will more than likely confuse students rather than introduce them to the real uses of inheritance.

    The more I hear about teachers like this, the more I'm convinced the saying is right: those who can, do; those who can't, teach.
    If I did your homework for you, then you might pass your class without learning how to write a program like this. Then you might graduate and get your degree without learning how to write a program like this. You might become a professional programmer without knowing how to write a program like this. Someday you might work on a project with me without knowing how to write a program like this. Then I would have to do you serious bodily harm. - Jack Klein

  8. #8
    Registered User
    Join Date
    Jul 2010
    Posts
    4

    btw

    I noticed that the user can insert the same stock number multiple times, and it needs to be unique. Any ideas as to how I can have it check to make sure that the value is not already in the List? I've been having trouble with that part. In my updated code, the Stock Number gets converted to type 'long' (didn't check if the post already has that).

  9. #9
    Anti-Poster
    Join Date
    Feb 2002
    Posts
    1,401
    A simple way is to use a Dictionary instead of List. In your case, because Stock Number is a property of Vehicle, I'd derive a VehicleDictionary from KeyedCollection<long, Vehicle>. The only method you have to override is GetKeyFromItem, and you'll be returning the stock number associated with the vehicle.
    If I did your homework for you, then you might pass your class without learning how to write a program like this. Then you might graduate and get your degree without learning how to write a program like this. You might become a professional programmer without knowing how to write a program like this. Someday you might work on a project with me without knowing how to write a program like this. Then I would have to do you serious bodily harm. - Jack Klein

  10. #10
    Registered User
    Join Date
    Mar 2009
    Location
    england
    Posts
    209
    If you must use a List, a simple lambda expression to check if the stock number exists would seem a reasonable way forward:

    Code:
    private bool AlreadyExists(long stocknumber)
    {
        return this.VehicleCollection.Find(x => x.StockNumber == stocknumber) != null;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. trouble with polymorphism
    By ichijoji in forum C++ Programming
    Replies: 1
    Last Post: 01-25-2006, 11:34 PM