ISC Practicals and Theory - Stock to Purchase/Sale
Updated 21 Oct 2026
A shop keeps an item in stock. When goods are purchased, the stock goes up and money is spent; when goods are sold, the stock comes down and money is earned. This note solves it by inheritance: a base class Stock holds what every transaction needs, and the derived classes Purchase and Sale add what is special to each. This is the classic form with default constructors and accept() and display() methods; the derived classes call the base class methods with super. A second version with parameterised constructors and method overriding is given under the OOP button.
Definition
Inheritance is the mechanism by which a derived class (subclass) acquires the data members and methods of a base class (superclass) using the keyword extends. The derived class can add its own members and can redefine a base class method; super.method() calls the base class version and super() calls the base class constructor.
Here, Purchase extends Stock and Sale extends Stock. A Purchase object has item, qty and rate from Stock and its own pqty and cost. For example, with 50 pens in stock at Rs. 12.50 and a purchase of 30, the stock becomes $50 + 30 = 80$ and the cost is $30 \times 12.50 = 375.00$.
The rules used in this program are a sample set, stated below. An ISC question gives its own, so use the question's rules in place of these.
- Opening stock must be 0 or more, the rate must be above 0 and the purchase and sale quantities must be 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 is left 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
main(in the driver classTest) creates aPurchaseobjectp.p.accept()callssuper.accept()ofStock, which reads the item, the opening stock and the rate and returnsfalseif the stock is negative or the rate is not above 0. Then it reads the purchased quantitypqtyand returnsfalseif it is less than 1. Iffalseis returned,mainprints the invalid input message and stops.p.update()addspqtytoqtyand findscost = pqty * rate.p.display()prints the quantity purchased and the cost, then callssuper.display()to print the item, the stock in hand and the rate.maincreates aSaleobjectsand callss.setStock()to give it the item, the stock and the rate ofp.s.accept()reads the quantity soldsqty(at least 1, else invalid input).s.sell()does the sale:- if
sqty > qtyit returnsfalseand the stock is unchanged; - otherwise it reduces
qtybysqty, findsamount = sqty * rate * (1 + margin / 100)and returnstrue.
- if
- If
sell()returnedtrue,maincallss.display(); otherwise it prints that the sale is rejected, with the stock in hand.
Program
Stock reads, stores and prints the common data; Purchase and Sale each add their own quantity, calculation and display; Test holds main. All the classes use one static Scanner declared in Stock, so that the typed input is read by a single Scanner. Sale.accept() reads only the quantity sold and does not call super.accept(), because the item, stock and rate are handed over by setStock().
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
static Scanner sc = new Scanner(System.in); // one Scanner shared by all the classes
/* Default constructor: sets the data members to their starting values. */
Stock()
{
item = "";
qty = 0;
rate = 0;
}
/* Reads the item, the opening stock and the rate.
Returns true if the values are valid (stock >= 0, rate > 0), otherwise false. */
boolean accept()
{
System.out.print("Enter the item name: ");
item = sc.next();
System.out.print("Enter the opening stock: ");
qty = sc.nextInt();
if (qty < 0)
return false;
System.out.print("Enter the rate per unit: ");
rate = sc.nextDouble();
if (rate <= 0)
return false;
return true;
}
/* Stores the given item, stock and rate (used to hand the stock on to a Sale object). */
void setStock(String i, int q, double r)
{
item = i;
qty = q;
rate = r;
}
/* 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
/* Default constructor: calls the base class constructor first, then sets its own members. */
Purchase()
{
super();
pqty = 0;
cost = 0;
}
/* Reads the stock details (super.accept()) and then the purchased quantity (must be >= 1).
Returns true if everything read is valid. */
boolean accept()
{
if (!super.accept())
return false;
System.out.print("Enter the quantity purchased: ");
pqty = sc.nextInt();
return pqty >= 1;
}
/* Adds the purchased quantity to the stock and finds the cost of the purchase. */
void update()
{
qty = qty + pqty;
cost = pqty * rate;
}
/* 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)
/* Default constructor: calls the base class constructor, then sets its own members. */
Sale()
{
super();
sqty = 0;
margin = 10;
amount = 0;
}
/* Reads the quantity to be sold (must be >= 1). The stock was set earlier by setStock().
Returns true if the quantity is valid. */
boolean accept()
{
System.out.print("Enter the quantity sold: ");
sqty = sc.nextInt();
return sqty >= 1;
}
/* Carries out the sale. Returns false (stock unchanged) if sqty is more than the stock;
otherwise reduces the stock, finds the sale amount and returns true. */
boolean sell()
{
if (sqty > qty)
return false;
qty = qty - sqty;
amount = sqty * rate * (1 + margin / 100);
return true;
}
/* 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, printing the stock after each. */
public static void main(String args[])
{
Purchase p = new Purchase(); // object for the purchase
if (!p.accept())
{
System.out.println("Invalid input. Stock must be 0 or more, rate above 0 and quantities at least 1.");
return;
}
p.update();
System.out.println("After the purchase:");
p.display();
Sale s = new Sale(); // object for the sale
s.setStock(p.item, p.qty, p.rate); // the sale starts with the stock left after the purchase
if (!s.accept())
{
System.out.println("Invalid input. Stock must be 0 or more, rate above 0 and quantities at least 1.");
return;
}
if (s.sell())
{
System.out.println("After the sale:");
s.display();
}
else
{
System.out.println("Sale rejected. Quantity sold is more than the stock in hand (" + s.qty + ").");
}
}
}Variable description table
| Variable | Data Type | Purpose |
|---|---|---|
item | String | Data member of Stock: name of the item (one word) |
qty | int | Data member of Stock: quantity of the item in stock |
rate | double | Data member of Stock: rate of one unit in rupees |
sc | Scanner | Static data member of Stock: reads everything typed by the user |
i | String | Parameter of setStock(): the item name to be stored |
q | int | Parameter of setStock(): the stock to be stored |
r | double | Parameter of setStock(): the rate to be stored |
pqty | int | Data member of Purchase: quantity purchased |
cost | double | Data member of Purchase: cost of the purchase, pqty * rate |
sqty | int | Data member of Sale: quantity sold |
margin | double | Data member of Sale: profit margin in percent (10) added to the rate |
amount | double | Data member of Sale: sale amount, sqty * rate * (1 + margin / 100) |
p | Purchase | Object of the derived class Purchase created in main |
s | Sale | Object of the derived class Sale created in main |
args | String[] | 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.50Sample 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.99Sample 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.Dry run
Take the first sample: item Pen, opening stock 50, rate 12.50, purchased 30, sold 20.
| Step | Statement | qty | pqty | cost | sqty | amount |
|---|---|---|---|---|---|---|
| 1 | p.accept() reads Pen, 50, 12.50, 30 | 50 | 30 | 0 | - | - |
| 2 | p.update(): qty = 50 + 30, cost = 30 * 12.5 | 80 | 30 | 375.00 | - | - |
| 3 | s.setStock("Pen", 80, 12.5) | 80 | - | - | 0 | 0 |
| 4 | s.accept() reads 20 | 80 | - | - | 20 | 0 |
| 5 | s.sell(): 20 > 80 is false, qty = 80 - 20, amount = 20 * 12.5 * 1.1 | 60 | - | - | 20 | 275.00 |
s.display() then 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 and 90 > 80 is true, so sell() returns false and the sale is rejected.
Variations
- Discount "Add a derived class that reduces the rate by a given percentage and prints the new rate."
- Margin from the user "Read the profit margin as input instead of fixing it at 10%."
- Another hierarchy "Write a base class
Accountand derived classesDepositandWithdraw, rejecting a withdrawal larger than the balance."