Prashnikaप्रश्निका
Code
About
‹ All Computer Science notes

ISC Practicals and Theory - Stock to Purchase/Sale (OOP)

Updated 21 Oct 2026

A shop keeps an item in stock: a purchase raises the stock and costs money, a sale lowers the stock and earns money. This version uses parameterised constructors that call the base class constructor with super(...), and the derived classes override the methods transact() and display(). In main, one reference of the base class type Stock first points to a Purchase object and then to a Sale object, so the call that runs depends on the object (dynamic binding). The classic version with default constructors is under the Classic button.

Definition

Inheritance lets a derived class acquire the members of a base class using extends. Method overriding means the derived class redefines a base class method with the same name and parameters. Polymorphism (dynamic binding) means that when a base class reference holds a derived class object, a call to an overridden method runs the derived class version, decided at run time. super(...) calls the base class constructor and super.display() calls the base class method.

For example, with Stock st = new Purchase("Pen", 50, 12.5, 30); the call st.transact() runs Purchase's version and the stock becomes $50 + 30 = 80$.

The rules used in this program are stated below, as the question gives no exact rules.

  • Opening stock must be 0 or more, the rate above 0 and the purchase and sale quantities at least 1; otherwise the input is invalid.
  • A sale is rejected if the quantity sold is more than the stock in hand, and the stock stays unchanged.
  • The sale rate is the purchase rate plus a 10% margin, so the sale amount is $\text{quantity sold} \times \text{rate} \times 1.10$.
  • The sale is made from the stock left after the purchase.

Algorithm

  1. main (in the driver class Test) reads the item, the opening stock, the rate and the purchased quantity with its own Scanner. After each value that has a limit it checks it, and if it is invalid it prints the invalid input message and stops.
  2. main creates Stock st = new Purchase(item, qty, rate, pq). The constructor of Purchase passes item, qty and rate to Stock with super(i, q, r) and stores pqty.
  3. st.transact() runs the overridden method of Purchase: it adds pqty to qty, finds cost = pqty * rate and returns true.
  4. st.display() runs Purchase's display(), which prints the quantity purchased and the cost and then calls super.display() to print the item, the stock in hand and the rate.
  5. main reads the quantity sold sq (at least 1, else invalid input) and makes st point to a new object new Sale(st.item, st.qty, st.rate, sq).
  6. st.transact() now runs Sale's method:
    • if sqty > qty it returns false and the stock is unchanged;
    • otherwise it reduces qty by sqty, finds amount = sqty * rate * (1 + margin / 100) and returns true.
  7. If transact() returned true, st.display() runs Sale's display(); otherwise main prints that the sale is rejected, with the stock in hand.

Program

Stock holds the common data and the base versions of transact() and display(); Purchase and Sale override both; Test holds main and uses a base class reference throughout.

import java.util.Scanner;

/* Class Stock: the base class. It holds the item, the quantity in stock and the rate. */
class Stock
{
    String item;                         // name of the item (one word)
    int qty;                             // quantity of the item in stock
    double rate;                         // rate (price) of one unit in rupees

    /* Parameterised constructor: sets the item, the stock and the rate. */
    Stock(String i, int q, double r)
    {
        item = i;
        qty = q;
        rate = r;
    }

    /* Does the transaction. The base class has none, so it only returns true.
       Purchase and Sale override this method. */
    boolean transact()
    {
        return true;
    }

    /* Prints the item, the stock in hand and the rate. */
    void display()
    {
        System.out.println("Item: " + item);
        System.out.println("Stock in hand: " + qty);
        System.out.printf("Rate per unit: %.2f%n", rate);
    }
}

/* Class Purchase: derived class. It adds the purchased quantity and the cost. */
class Purchase extends Stock
{
    int pqty;                            // quantity purchased
    double cost;                         // cost of the purchase = pqty * rate

    /* Parameterised constructor: passes item, stock and rate to the base class with super(...). */
    Purchase(String i, int q, double r, int p)
    {
        super(i, q, r);
        pqty = p;
        cost = 0;
    }

    /* Overrides transact(): adds the purchased quantity to the stock and finds the cost.
       Always returns true, as a purchase is never rejected. */
    boolean transact()
    {
        qty = qty + pqty;
        cost = pqty * rate;
        return true;
    }

    /* Overrides display(): prints the purchase details and then the stock (super.display()). */
    void display()
    {
        System.out.println("Quantity purchased: " + pqty);
        System.out.printf("Purchase cost: %.2f%n", cost);
        super.display();
    }
}

/* Class Sale: derived class. It adds the quantity sold and the sale amount. */
class Sale extends Stock
{
    int sqty;                            // quantity sold
    double margin;                       // profit margin in percent added to the rate
    double amount;                       // sale amount = sqty * rate * (1 + margin / 100)

    /* Parameterised constructor: passes item, stock and rate to the base class with super(...). */
    Sale(String i, int q, double r, int s)
    {
        super(i, q, r);
        sqty = s;
        margin = 10;
        amount = 0;
    }

    /* Overrides transact(): returns false (stock unchanged) if sqty is more than the stock;
       otherwise reduces the stock, finds the sale amount and returns true. */
    boolean transact()
    {
        if (sqty > qty)
            return false;
        qty = qty - sqty;
        amount = sqty * rate * (1 + margin / 100);
        return true;
    }

    /* Overrides display(): prints the sale details and then the stock (super.display()). */
    void display()
    {
        System.out.println("Quantity sold: " + sqty);
        System.out.printf("Sale amount (rate + %.0f%% margin): %.2f%n", margin, amount);
        super.display();
    }
}

/* Class Test: the driver class that holds main. */
public class Test
{
    /* Reads the data, makes a purchase and then a sale using one Stock reference,
       printing the stock after each. */
    public static void main(String args[])
    {
        Scanner sc = new Scanner(System.in);   // reads the typed values
        String msg = "Invalid input. Stock must be 0 or more, rate above 0 and quantities at least 1.";
        System.out.print("Enter the item name: ");
        String item = sc.next();               // name of the item
        System.out.print("Enter the opening stock: ");
        int qty = sc.nextInt();                // opening stock
        if (qty < 0)
        {
            System.out.println(msg);
            return;
        }
        System.out.print("Enter the rate per unit: ");
        double rate = sc.nextDouble();         // rate per unit
        if (rate <= 0)
        {
            System.out.println(msg);
            return;
        }
        System.out.print("Enter the quantity purchased: ");
        int pq = sc.nextInt();                 // quantity purchased
        if (pq < 1)
        {
            System.out.println(msg);
            return;
        }

        Stock st = new Purchase(item, qty, rate, pq);   // base class reference to a Purchase object
        st.transact();                         // calls Purchase's transact()
        System.out.println("After the purchase:");
        st.display();                          // calls Purchase's display()

        System.out.print("Enter the quantity sold: ");
        int sq = sc.nextInt();                 // quantity sold
        if (sq < 1)
        {
            System.out.println(msg);
            return;
        }
        st = new Sale(st.item, st.qty, st.rate, sq);    // the same reference now points to a Sale object
        if (st.transact())                     // calls Sale's transact()
        {
            System.out.println("After the sale:");
            st.display();                      // calls Sale's display()
        }
        else
        {
            System.out.println("Sale rejected. Quantity sold is more than the stock in hand (" + st.qty + ").");
        }
    }
}

Variable description table

VariableData TypePurpose
itemStringData member of Stock: name of the item; also the local in main that holds the typed name
qtyintData member of Stock: quantity in stock; also the local in main that holds the opening stock
ratedoubleData member of Stock: rate of one unit in rupees; also the local in main that holds the typed rate
iStringParameter of the constructors: the item name
qintParameter of the constructors: the stock
rdoubleParameter of the constructors: the rate
pqtyintData member of Purchase: quantity purchased
costdoubleData member of Purchase: cost of the purchase, pqty * rate
pintParameter of the Purchase constructor: the quantity purchased
sqtyintData member of Sale: quantity sold
margindoubleData member of Sale: profit margin in percent (10) added to the rate
amountdoubleData member of Sale: sale amount, sqty * rate * (1 + margin / 100)
sintParameter of the Sale constructor: the quantity sold
scScannerLocal in main: reads everything typed by the user
msgStringLocal in main: the invalid input message
pqintLocal in main: the quantity purchased typed by the user
sqintLocal in main: the quantity sold typed by the user
stStockBase class reference in main, pointing first to a Purchase and then to a Sale object
argsString[]Command-line arguments of main (not used)

Sample input and output

Sample 1

Enter the item name: Pen
Enter the opening stock: 50
Enter the rate per unit: 12.50
Enter the quantity purchased: 30
After the purchase:
Quantity purchased: 30
Purchase cost: 375.00
Item: Pen
Stock in hand: 80
Rate per unit: 12.50
Enter the quantity sold: 20
After the sale:
Quantity sold: 20
Sale amount (rate + 10% margin): 275.00
Item: Pen
Stock in hand: 60
Rate per unit: 12.50

Sample 2

Enter the item name: Pen
Enter the opening stock: 50
Enter the rate per unit: 12.50
Enter the quantity purchased: 30
After the purchase:
Quantity purchased: 30
Purchase cost: 375.00
Item: Pen
Stock in hand: 80
Rate per unit: 12.50
Enter the quantity sold: 90
Sale rejected. Quantity sold is more than the stock in hand (80).

Sample 3

Enter the item name: Book
Enter the opening stock: 0
Enter the rate per unit: 99.99
Enter the quantity purchased: 10
After the purchase:
Quantity purchased: 10
Purchase cost: 999.90
Item: Book
Stock in hand: 10
Rate per unit: 99.99
Enter the quantity sold: 10
After the sale:
Quantity sold: 10
Sale amount (rate + 10% margin): 1099.89
Item: Book
Stock in hand: 0
Rate per unit: 99.99

Sample 4

Enter the item name: Pen
Enter the opening stock: -5
Invalid input. Stock must be 0 or more, rate above 0 and quantities at least 1.

One value per line

Dry run

Take the first sample: item Pen, opening stock 50, rate 12.50, purchased 30, sold 20.

StepStatementObject st points toqtypqty or sqtycost or amount
1new Purchase("Pen", 50, 12.5, 30)Purchase50pqty = 30cost = 0
2st.transact(): qty = 50 + 30, cost = 30 * 12.5Purchase80pqty = 30cost = 375.00
3new Sale("Pen", 80, 12.5, 20)Sale80sqty = 20amount = 0
4st.transact(): 20 > 80 is false, qty = 80 - 20, amount = 20 * 12.5 * 1.1Sale60sqty = 20amount = 275.00

st.display() then runs Sale's display() and prints the quantity sold, the sale amount 275.00 and the stock in hand 60, as in the first sample run. In the second sample sqty = 90, 90 > 80 is true, so Sale's transact() returns false and the sale is rejected.

Variations

  1. Discount "Add a derived class that reduces the rate by a given percentage and overrides display() to print the new rate."
  2. Margin from the user "Read the profit margin as input instead of fixing it at 10%."
  3. Another hierarchy "Write a base class Account and derived classes Deposit and Withdraw, each overriding a method transact(); reject a withdrawal larger than the balance."