c# – Creating objects from generic parent classes

In the previous unit we came across:

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

namespace InheritenceInAction
{
    class Program
    {
        static void Main(string[] args)
        {
            // Here we create an object using the orange class
            Orange AnOrange = new Orange(1.25, 45, "Spain", "25-01-2015", "sweet", true, "clementine");
            string ContainsSeedsSentence;
            if (AnOrange.ContainsSeeds)
            {
                ContainsSeedsSentence = "This fruit contains seeds.";
            }
            else
            {
                ContainsSeedsSentence = "This fruit is seedless.";
            }

            Console.WriteLine("\n\nThis {0} is a {1} and is grown in {2} and costs  £{3}. It's a {4} fruit and contains {5} calories. It's use-by date is {6}. {7}",
            AnOrange.FruitName, AnOrange.OrangeType, AnOrange.CountryOfOrigin, AnOrange.Price, AnOrange.SweetnessLevel, AnOrange.Calories, AnOrange.UseByDate, ContainsSeedsSentence);

            // Here we create an object using the banana class
            Banana ABanana = new Banana(0.43, 135, "Kenya", "25-05-2014", " very sweet", false, "Cavendish");
            if (ABanana.ContainsSeeds)
            {
                ContainsSeedsSentence = "This fruit contains seeds.";
            }
            else
            {
                ContainsSeedsSentence = "This fruit is seedless.";
            }
            Console.WriteLine("\n\nThis {0} is a {1} and is grown in {2} and costs  £{3}. It's a {4} fruit and contains {5} calories. It's use-by date is {6}. {7}",
            ABanana.FruitName, ABanana.BananaType, ABanana.CountryOfOrigin, ABanana.Price, ABanana.SweetnessLevel, ABanana.Calories, ABanana.UseByDate, ContainsSeedsSentence);
            Console.ReadLine();
        }
    }

    class Item
    {
        public double Price { get; set; }
        public string CountryOfOrigin { get; set; }
    }

    class Food : Item
    {

        public int Calories { get; set; }

        public string UseByDate { get; set; }

    }

    class Fruit : Food
    {

        public string SweetnessLevel { get; set; }
        public bool ContainsSeeds { get; set; }

    }

    class Orange : Fruit
    {

        private string fruitname;
        public string FruitName
        {
            get { return fruitname; }
            set { fruitname = "Orange"; }
        }
        // notice that we have expanded the Fruitname property above, because we want it to be a constant.
        // All other properties are defined in the standard way below:

        public string OrangeType { get; set; }

        public Orange(double Price, int Calories, string CountryOfOrigin, string UseByDate, string SweetnessLevel, bool ContainsSeeds, string OrangeType)
        {
            FruitName = FruitName;		// This is inserted to trigger the FruitName property's set element.
            this.Price = Price;
            this.Calories = Calories;
            this.CountryOfOrigin = CountryOfOrigin;
            this.UseByDate = UseByDate;
            this.SweetnessLevel = SweetnessLevel;
            this.ContainsSeeds = ContainsSeeds;
            this.OrangeType = OrangeType;
        }
    }

    class Banana : Fruit
    {
        private string fruitname;
        public string FruitName
        {
            get { return fruitname; }
            set { fruitname = "Banana"; }
        }
        public string BananaType { get; set; }

        public Banana(double Price, int Calories, string CountryOfOrigin, string UseByDate, string SweetnessLevel, bool ContainsSeeds, string BananaType)
        {
            FruitName = FruitName;   // This is inserted to trigger the FruitName property's set element.
            this.Price = Price;
            this.Calories = Calories;
            this.CountryOfOrigin = CountryOfOrigin;
            this.UseByDate = UseByDate;
            this.SweetnessLevel = SweetnessLevel;
            this.ContainsSeeds = ContainsSeeds;
            this.BananaType = BananaType;
        }
    }
}

In C# you can create an object using the parent class, but instantiate it with a child classe’s constructor method, e.g.:

This means that the object is technically an “item” object and not an “orange” object.

However you can convert high level object to the object that it has been constructed by using the following notation, highlighted:

After that, the new object variable can now access the properties that it has been hiding:

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

namespace InheritenceInAction
{
    class Program
    {
        static void Main(string[] args)
        {
            Item AnOrange = new Orange(1.25, 45, "Spain", "25-01-2015", "sweet", true, "clementine");

            Orange AnotherOrange = AnOrange as Orange;

            Console.WriteLine("\n\nThis {0} is a {1} and is grown in {2} and costs  £{3}. It's a {4} fruit and contains {5} calories. It's use-by date is {6}.",
            AnotherOrange.FruitName, AnotherOrange.OrangeType, AnotherOrange.CountryOfOrigin, AnotherOrange.Price, AnotherOrange.SweetnessLevel, AnotherOrange.Calories, AnotherOrange.UseByDate);
            Console.ReadLine();
        }
    }

    class Item
    {
        public double Price { get; set; }
        public string CountryOfOrigin { get; set; }
    }

    class Food : Item
    {

        public int Calories { get; set; }

        public string UseByDate { get; set; }

    }

    class Fruit : Food
    {

        public string SweetnessLevel { get; set; }
        public bool ContainsSeeds { get; set; }

    }

    class Orange : Fruit
    {

        private string fruitname;
        public string FruitName
        {
            get { return fruitname; }
            set { fruitname = "Orange"; }
        }

        public string OrangeType { get; set; }

        public Orange(double Price, int Calories, string CountryOfOrigin, string UseByDate, string SweetnessLevel, bool ContainsSeeds, string OrangeType)
        {
            FruitName = FruitName;		// This is inserted to trigger the FruitName property's set element.
            this.Price = Price;
            this.Calories = Calories;
            this.CountryOfOrigin = CountryOfOrigin;
            this.UseByDate = UseByDate;
            this.SweetnessLevel = SweetnessLevel;
            this.ContainsSeeds = ContainsSeeds;
            this.OrangeType = OrangeType;
        }
    }

}

This will output:

This technique is useful if you want to create an object, but only makes it’s lower level info available later on.