ISC Practicals and Theory - Detail to Bill
Updated 21 Oct 2026
A telephone bill is a classic use of inheritance: the details of a subscriber (name, address, number, rent) are kept in a base class Detail, and a derived class Bill adds the number of calls and works out the amount payable. This is the standard form of the program: default constructors, an accept() and a display() in each class, and the derived class calling the base class methods with super.
Definition
Inheritance lets a derived class (written class Bill extends Detail) take the data members and methods of a base class and add its own. A method of the base class that the derived class writes again with the same name and parameters is redefined (overridden); super.method() calls the base class version from inside it.
The bill follows a slab rule. These figures are a sample set; a question paper states its own slabs and rates, so use the question's figures in place of these:
- the first 100 calls are free;
- calls 101 to 200 cost Rs 1.00 each;
- calls 201 to 300 cost Rs 1.20 each;
- calls beyond 300 cost Rs 1.50 each;
- a surcharge of 5% is added on (rent + call charge).
Bill amount = rent + call charge + surcharge. For example, with rent Rs 300 and 250 calls: call charge $= 100 \times 1.00 + 50 \times 1.20 = 160$, surcharge $= 5\%$ of $460 = 23$, bill $= 300 + 160 + 23 = 483$.
Rent and the number of calls must not be negative; otherwise the program prints INVALID INPUT.
Algorithm
main(in the driver classTest) creates an objectobof the derived classBill. The constructorBill()sets the new data members to 0, after the base constructorDetail()has setname,address,telandrent.maincallsob.accept(), which is theaccept()ofBill:- it first calls
super.accept(), theaccept()ofDetail, which reads the name, address, telephone number and rent, and returnsfalseif the rent is negative; - if that returned
false,Bill'saccept()returnsfalseat once; - otherwise it reads
callsand returnsfalseif it is negative, elsetrue.
- it first calls
- If
accept()returnedfalse,mainprintsINVALID INPUTand stops. - Otherwise
maincallsob.calculate():- if
callsis 100 or less,callCharge = 0; - else if
callsis 200 or less,callCharge = (calls - 100) * 1.00; - else if
callsis 300 or less,callCharge = 100 * 1.00 + (calls - 200) * 1.20; - else
callCharge = 100 * 1.00 + 100 * 1.20 + (calls - 300) * 1.50; tax = (rent + callCharge) * 5 / 100andtotal = rent + callCharge + tax.
- if
maincallsob.display(), thedisplay()ofBill. It callssuper.display()to print the details and rent, then prints the calls, call charge, surcharge and bill amount, each to 2 decimal places withprintf("%.2f").
Program
Detail holds and reads the subscriber's data, Bill adds the calls and the calculation, and Test only holds main. The Scanner is a static member of Detail, so both classes read from the same one.
import java.util.Scanner;
/* Base class: the details of a telephone subscriber. */
class Detail
{
String name; // name of the subscriber
String address; // address of the subscriber
String tel; // telephone number (kept as text, it is not used in arithmetic)
double rent; // monthly rent in rupees
static Scanner sc = new Scanner(System.in); // one Scanner shared by Detail and Bill
/* Default constructor: gives every data member an initial value. */
Detail()
{
name = "";
address = "";
tel = "";
rent = 0.0;
}
/* Reads name, address, telephone number and rent.
Returns true if the rent is valid (0 or more), otherwise false. */
boolean accept()
{
System.out.print("Enter name: ");
name = sc.nextLine();
System.out.print("Enter address: ");
address = sc.nextLine();
System.out.print("Enter telephone number: ");
tel = sc.nextLine();
System.out.print("Enter monthly rent (Rs): ");
rent = sc.nextDouble();
if (rent < 0) // a negative rent is not possible
{
return false;
}
return true;
}
/* Prints the subscriber's details and the rent. */
void display()
{
System.out.println("Name : " + name);
System.out.println("Address : " + address);
System.out.println("Telephone : " + tel);
System.out.printf("Rent : Rs %.2f%n", rent);
}
}
/* Derived class: a Detail plus the calls made, from which the bill is worked out. */
class Bill extends Detail
{
int calls; // number of calls made in the month
double callCharge; // charge for the calls, by slabs
double tax; // surcharge on (rent + call charge)
double total; // final bill amount
final int SLAB = 100; // size of each slab of calls
final double RATE1 = 1.00; // Rs per call, calls 101 to 200
final double RATE2 = 1.20; // Rs per call, calls 201 to 300
final double RATE3 = 1.50; // Rs per call, beyond 300
final double TAXPER = 5.0; // surcharge percentage
/* Default constructor: sets the new data members to 0. */
Bill()
{
calls = 0;
callCharge = 0.0;
tax = 0.0;
total = 0.0;
}
/* Calls the base class accept() and then reads the number of calls.
Returns true only if the rent and the calls are both valid. */
boolean accept()
{
if (!super.accept()) // stop at once if the rent was invalid
{
return false;
}
System.out.print("Enter number of calls: ");
calls = sc.nextInt();
if (calls < 0) // a negative number of calls is not possible
{
return false;
}
return true;
}
/* Works out callCharge, tax and total using the slab rule. */
void calculate()
{
if (calls <= SLAB) // first 100 calls are free
{
callCharge = 0;
}
else if (calls <= 2 * SLAB) // next 100 calls at RATE1
{
callCharge = (calls - SLAB) * RATE1;
}
else if (calls <= 3 * SLAB) // next 100 calls at RATE2
{
callCharge = SLAB * RATE1 + (calls - 2 * SLAB) * RATE2;
}
else // calls beyond 300 at RATE3
{
callCharge = SLAB * RATE1 + SLAB * RATE2 + (calls - 3 * SLAB) * RATE3;
}
tax = (rent + callCharge) * TAXPER / 100; // surcharge on rent + call charge
total = rent + callCharge + tax;
}
/* Prints the details through the base class, then the bill. */
void display()
{
super.display();
System.out.println("Calls : " + calls);
System.out.printf("Call charge : Rs %.2f%n", callCharge);
System.out.printf("Surcharge : Rs %.2f%n", tax);
System.out.printf("Bill amount : Rs %.2f%n", total);
}
}
/* Driver class: holds main. */
public class Test
{
/* Creates one Bill object and runs accept, calculate and display. */
public static void main(String args[])
{
Bill ob = new Bill(); // object of the derived class
if (ob.accept())
{
ob.calculate();
ob.display();
}
else
{
System.out.println("INVALID INPUT");
}
}
}Variable description table
| Variable | Data Type | Purpose |
|---|---|---|
name | String | Data member of Detail: name of the subscriber |
address | String | Data member of Detail: address of the subscriber |
tel | String | Data member of Detail: telephone number, kept as text |
rent | double | Data member of Detail: monthly rent in rupees |
sc | Scanner | Static data member of Detail: reads all the input |
calls | int | Data member of Bill: number of calls made in the month |
callCharge | double | Data member of Bill: charge for the calls by slabs |
tax | double | Data member of Bill: surcharge on rent plus call charge |
total | double | Data member of Bill: the final bill amount |
SLAB | int | Constant: size of each slab of calls (100) |
RATE1 | double | Constant: rupees per call for calls 101 to 200 |
RATE2 | double | Constant: rupees per call for calls 201 to 300 |
RATE3 | double | Constant: rupees per call beyond 300 |
TAXPER | double | Constant: surcharge percentage |
ob | Bill | Object of the derived class created in main |
args | String[] | Command-line arguments of main (not used) |
Sample input and output
Sample 1
Enter name: Asha Rao
Enter address: 12 MG Road
Enter telephone number: 9876543210
Enter monthly rent (Rs): 300
Enter number of calls: 250
Name : Asha Rao
Address : 12 MG Road
Telephone : 9876543210
Rent : Rs 300.00
Calls : 250
Call charge : Rs 160.00
Surcharge : Rs 23.00
Bill amount : Rs 483.00Sample 2
Enter name: Meena Iyer
Enter address: 7 Lake View
Enter telephone number: 2456789
Enter monthly rent (Rs): 200
Enter number of calls: 350
Name : Meena Iyer
Address : 7 Lake View
Telephone : 2456789
Rent : Rs 200.00
Calls : 350
Call charge : Rs 295.00
Surcharge : Rs 24.75
Bill amount : Rs 519.75Sample 3
Enter name: Kiran Shah
Enter address: 3 Hill Road
Enter telephone number: 5551234
Enter monthly rent (Rs): 300
Enter number of calls: 0
Name : Kiran Shah
Address : 3 Hill Road
Telephone : 5551234
Rent : Rs 300.00
Calls : 0
Call charge : Rs 0.00
Surcharge : Rs 15.00
Bill amount : Rs 315.00Sample 4
Enter name: Ravi Kumar
Enter address: 5 Park Street
Enter telephone number: 2234567
Enter monthly rent (Rs): 250
Enter number of calls: -3
INVALID INPUTDry run
Take the first sample: rent $= 300$, calls $= 250$. After accept(), rent is 300.0 and calls is 250. calculate() goes through these steps:
| Step | Test or statement | Value |
|---|---|---|
| 1 | calls <= 100 | false (250 > 100) |
| 2 | calls <= 200 | false |
| 3 | calls <= 300 | true |
| 4 | callCharge = 100 * 1.00 + (250 - 200) * 1.20 | 160.0 |
| 5 | tax = (300 + 160) * 5 / 100 | 23.0 |
| 6 | total = 300 + 160 + 23 | 483.0 |
display() then prints the details through super.display() followed by 250, 160.00, 23.00 and 483.00, so the last line is Bill amount : Rs 483.00, as in the first sample run.
Variations
- Slabs by units "Write a program to compute an electricity bill from the units consumed using a slab rate, with a class for the consumer's details and a derived class for the bill."
- Minimum charge "Modify the bill so that a minimum amount is payable even when no calls are made."
- Three-level inheritance "Add a third class derived from
Billthat applies a discount for prompt payment."