Wrox Programmer Forums
Go Back   Wrox Programmer Forums > C# and C > C# 1.0 > C#
|
C# Programming questions specific to the Microsoft C# language. See also the forum Beginning Visual C# to discuss that specific Wrox book and code.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the C# section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old October 10th, 2005, 02:26 PM
Authorized User
 
Join Date: Apr 2005
Posts: 10
Thanks: 0
Thanked 0 Times in 0 Posts
Default question about abstract class/polymorphism

I am having trouble understanding the concept of abstract class while using the concept of polymorphism.

I have an understanding of certain concepts correct me if I am wrong.

INSTANCIATING AN OBJECT

public class Account()
{
//has couple of methods and contructors defined in this class
}

public class testAccount()
{
  Account acc; // acc is a reference to an Account object;
               // the object itself does not yet exist.

  acc = new Account(); // Account object now exists and
                       //acc is a reference to it

}//testAccount

Is this right? Ok then when you come to the definition of Abstract class..
ABSTRACT CLASS: An abstract class is basically a template to be followed by various derived classes. for example say classes such as SavingsAccount() and CheckingAccount() are derived from the base class Account(). Also, an abstract class CANNOT be instantiated..right??

so finally my question is in this code: Please do follow the code carefully as it uses enum, polymorphism, abstract class, virtual/override concepts in this code.

//Account.cs file
abstract public class Account
{
   private int id;
   protected decimal balance;
    private string owner;
    protected int numXact = 0; // number of transactions
    public Account(decimal balance, string owner, int id)
    {
        this.balance = balance;
        this.owner = owner;
        this.id = id;
    }
    virtual public void Deposit(decimal amount)
    {
        balance += amount;
        numXact++;
    }
    virtual public void Withdraw(decimal amount)
    {
        balance -= amount;
        numXact++;
    }
    public decimal Balance
    {
        get
        {
            return balance;
        }
    }
    public int Id
    {
        get
        {
            return id;
        }
    }
    public string Owner
    {
        get
        {
            return owner;
        }
        set
        {
            owner = value;
        }
    }
    public int Transactions
    {
        get
        {
            return numXact;
        }
    }
    virtual public string GetStatement()
    {
     string s = "Statement for " + this.Owner + " id = " +
         + Id + "\n" +
     this.Transactions + " transactions, balance = " + balance;
        return s;
    }
    abstract public void Post();
    abstract public string Prompt {get;}
    virtual public void MonthEnd()
    {
        numXact = 0;
    }
}

//CheckingAccount.cs
using System;

public class CheckingAccount : Account
{
    private decimal fee = 5.00m;
    private const int FREEXACT = 2;
    public CheckingAccount(decimal balance, string owner, int id)
        : base(balance, owner, id)
    {
    }
    public decimal Fee
    {
        get
        {
            if (numXact > FREEXACT)
                return fee;
            else
                return 0.00m;
        }
    }
    override public string GetStatement()
    {
        string s = base.GetStatement();
        s += ", fee = " + Fee;
        return s;
    }
    override public void Post()
    {
        balance -= Fee;
    }
    override public string Prompt
    {
        get
        {
            return "C: ";
        }
    }
}

//SavingsAccount.cs
using System;

public class SavingsAccount : Account
{
    private decimal minBalance;
    private decimal rate = 0.06m;
    public SavingsAccount(decimal balance, string owner, int id)
        : base(balance, owner, id)
    {
        minBalance = balance;
    }
    public decimal Interest
    {
        get
        {
            return minBalance * rate/12;
        }
    }
    override public void Withdraw(decimal amount)
    {
        base.Withdraw(amount);
        if (balance < minBalance)
        {
            minBalance = balance;
        }
    }
    override public void Post()
    {
        balance += Interest;
    }
    override public string GetStatement()
    {
        string s = base.GetStatement();
        s += ", interest = " + Interest;
        return s;
    }
    public decimal Rate
    {
        get
        {
            return rate;
        }
        set
        {
            rate = value;
        }
    }
    override public string Prompt
    {
        get
        {
            return "S: ";
        }
    }
    override public void MonthEnd()
    {
        base.MonthEnd();
        minBalance = balance;
    }
}

//Bank.cs
using System;

public enum AccountType
{
    Checking,
    Savings,
    Invalid
}

public class Bank
{
    private Account[] accounts;
        private int nextid = 1;
    private int count = 0;
    public Bank()
    {
        accounts = new Account[10]; //so how can one instantiate an abstract class??
        AddAccount(AccountType.Checking, 100, "Bob");
        AddAccount(AccountType.Savings, 200, "Mary");
        AddAccount(AccountType.Checking, 300, "Charlie");
    }
    public int AddAccount(AccountType type, decimal bal, string owner)
    {
        Account acc;
        int id = nextid++;
        switch(type)
        {
            case AccountType.Checking:
             acc = new CheckingAccount(bal, owner, id);
                break;
            case AccountType.Savings:
             acc = new SavingsAccount(bal, owner, id);
                break;
            default:
             Console.WriteLine("Unexpected AccountType");
                return -1;
        }
        accounts[count++] = acc;
        return id;
    }
    public string[] GetAccounts()
    {
        string[] array = new string[count];
        for (int i = 0; i < count; i++)
        {
            string owner = accounts[i].Owner;
            string stype = accounts[i].Prompt;
            string sid = accounts[i].Id.ToString();
            string sbal = accounts[i].Balance.ToString();
            string str = sid + "\t" + stype + owner + "\t" + sbal;
            array[i] = str;
        }
        return array;
    }
    public void DeleteAccount(int id)
    {
        int index = FindIndex(id);
        if (index != -1)
        {
            // move accounts down
            for (int i = index; i < count; i++)
            {
                accounts[i] = accounts[i+1];
            }
            count--;
        }
    }
    private int FindIndex(int id)
    {
        for (int i = 0; i < count; i++)
        {
            if (accounts[i].Id == id)
                return i;
        }
        return -1;
    }
    public Account FindAccount(int id)
    {
        for (int i = 0; i < count; i++)
        {
            if (accounts[i].Id == id)
                return accounts[i];
        }
        return null;
    }
}


For the convenience of the friends try to help me in understanding this concept I am reiterating the question.
How can an abstract class object be instantiated in the Bank class.
 
Old October 10th, 2005, 02:51 PM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 440
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Alright AFAIK...

The term object is used for an instance of a class. So to be exact I would say that you are actually instantiating a class; i.e. making an instance of a class (the object).

In the first part I would say you are right; i.e. to make an instance of the Account class.

And yes, the abstract class is like a way to do derived classes, like a recipe on how to do it. The thing you are doing when you create an array of the abstract type is not instantiating a series of that object.

What you are doing is allocating enough space to hold a series of objects of that type, and therefore you have to instantiate the entries in the array with objects of the exact type, and thats exactly what you are doing in AddAccount.

Hope it helps, Jacob.
 
Old October 10th, 2005, 04:39 PM
Authorized User
 
Join Date: Apr 2005
Posts: 10
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thank you Jacob for a quick reply. I have one more question..I think I have still did not get this idea properly (partially got your end of explanation)

when we say
CASE 1:

Account acc = new Account();
// an object of type Account is created and acc is referring to it...is that right?


so could you tell how it would be pictorially in case 1?


(CASE 2):
and when you say
Account[] acc = new Account[10]
//you are saying :"What you are doing is allocating enough space to hold a series of objects of that type, and therefore you have to instantiate the entries in the array with objects of the exact type, and thats exactly what you are doing in AddAccount"..........:)


 I could understand what you are saying but could not imagine pictorially...If possible could you give a pictorial view of memory in both cases.

Also till now I was under the opinion that if you find a new (apart from new/hide modifiers in inheritance) operator then you are instantiating an object of that particular class. Is that not true?
if it is true...why is it that in second case it is not instantiating and it is in the first case.
Thank you in advance
csharplearner
 
Old October 11th, 2005, 03:39 AM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 440
Thanks: 0
Thanked 0 Times in 0 Posts
Default

In case 1 you are right. In fact the new operator allocates memory for the Account object; i.e. when using the new operator you are dynamically allocating memory for the object. And yes the acc is a reference to this object.

In case 2 you have this...
Code:
Account[] acc = new Account[10];
... which both declare the array (first part), and then dynamically allocate the memory needed for the array of size 10. Later you instantiate the actual objects needed at each position in the array. I guess you can imagine the first declaration as the construction of the container for the objects and then the second part as the construction of the elements in the container.

E.g. when dealing with string arrays dynamically using C you have to make char double pointer; first level for the array entries and the second level for the strings (char*).

Hope it helps, Jacob.
 
Old October 11th, 2005, 03:27 PM
Authorized User
 
Join Date: Apr 2005
Posts: 10
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thank you Jacob. It helped a lot






Similar Threads
Thread Thread Starter Forum Replies Last Post
A question about abstract class nf0001384 C# 2005 5 July 22nd, 2013 06:58 AM
polymorphism and abstract classes elvisfeverr C++ Programming 3 October 16th, 2008 01:39 AM
Why abstract class can't be instantiated? anisurr C++ Programming 5 July 23rd, 2008 01:32 AM
interface and abstract class sreenu.pocha C# 2 July 26th, 2006 07:18 AM
How to write abstract class to xml haiying General .NET 4 September 21st, 2004 08:32 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.