Parts 1-3 of Product / Inventory Project

One of the many questions we are asked on a regular basis is help with the Product, DVD, Inventory inheritance style of problem. Where the student is asked to create a Product class as part 1, then create an Inventory class in part2 to manage the products, and lastly asked to inherit from the Product class to make a specialized subclass in part 3. While this blog entry goes into depth with examples from Java, you can easily adapt it to C++ with a little tweaking. The principles are similar and pretty much the same other than syntax. So get read to…. ROCK AND ROLLLLLLL on this episode of the Programming Underground!

This project is one that is done over and over again with students new to programming. So I thought “Why not show the project in its parts and help out our readers on Dream.In.Code?” I know how it is to be a computer science student trying to get the language down while trying to meet deadlines. I hear your pain! I will be the cure and talk about the steps as we go through some examples.

Part 1 – The product class

This part is crucial to get right before continuing. With a strong product class, you form a nice foundation for the rest of the parts to come. It is like the foundation of a building, it has to be strong like when I go to the rim in basketball. Oh who am I kidding? The ball even pushes me around like a school bully.

Build this class correctly first and the rest of the parts will flow more naturally. It is not a hard part to do, but should be tested well. The classic project asks that you create a Product class that has several elements including a product id, name, quantity, and price. This list of items should tell you right there that you will need variables to hold all those values and ways to change and read them from your class. Let’s take a look!

public class Product {
	// Private variables
	private String name;
	private int quantity;
	private double price;
	private int productid = 0;

	// Default constructor uses other constructor to set the
	// default state of the object.

	public Product() {
		this(0,"Unknown",0,0.00);
	}

	// Constructor that user can specify a name, quantity, and price for for items.
	public Product(int productId, String itemname, int quantityOnHand, double itemprice) {
		productid = productId;
		setName(itemname);
		setQuantityOnHand(quantityOnHand);
		setPrice(itemprice);
	}


	// Public mutators (changes state of the object)
	public void setName(String itemname) {
		name = itemname;
	}


	// Sets quantity on hand and if negative, defaults to zero.
	public void setQuantityOnHand(int quantityOnHand) {
		if (quantityOnHand > 0) {
			quantity = quantityOnHand;
		}
		else { quantity = 0; }
	}


	// Set price of a product and defaults it to zero if negative.
	public void setPrice(double itemPrice) {
		if (itemPrice > 0.00) {
			price = itemPrice;
		}
		else { price = 0.00; }
	}

	// Get the product's name
	public String getName() {
		return name;
	}

	public int getQuantityOnHand() {
		return quantity;
	}

	public double getPrice() {
		return price;
	}

	// Calculate the value of stock on this particular item.
	public double getItemValue() {
		return (price * (double)quantity);
	}

	// String representation of the product
	public String toString() {
		return name + " - " + price;
	}
}

This class is pretty straight forward. You got variables to hold all the parts and a set of methods to set them (also known as mutator functions and begin with “set”) and a bunch of functions to read the values (also known as accessors and begin with “get”). This class has one extra feature that is not usually asked for by most assignments and that is an overridden constructor. Notice how we have two constructors that share the same name as the class “Product”. The one that takes no parameters actually uses the keyword “this” to call the other constructor with default values. This is not needed, but if you wanted to create an empty product for some reason and configure it later with your mutator functions you could. Like when your teacher is not looking and you want to setup your own underground horse betting casino and the products are horse odds to win.

Also note that this class has a toString() implementation which basically spits out the name of the product and its price. Not too bad right? Read through the in code comments to see where everything is located and how things work. Pay special attention to getItemValue() here where we multiple the quantity we have and the price to get a total stock value for this particular product. It will be overridden later in part3 to include a restocking fee.

Part 2 – Inventory Class

This class is designed to be a “wrapper” class. This means that it “wraps around” an internal structure (an array of products) and has functions that support the manipulation of this array. Like adding products to it, looping through the items to find out information like total stock value etc. Most projects at this stage require a feature that gets the total inventory value, printing out all the items in inventory and the ability to add products.

// Import the format class to format values into currency format.
import java.text.DecimalFormat;

// Inventory class, used to manage a bunch of Product classes.

public class Inventory {
	// Setup an array of Products (set it to hold 30 items)
	int inventorySize = 30;
	private Product items[] = new Product[inventorySize];

	// Set the formatter to format values into currency form.
	DecimalFormat formatter = new DecimalFormat("$##,###.00");

	// Adds a product to the array of products. Adds to first empty slot found.
	public void addProduct(Product item) {
		for (int i = 0; i < inventorySize; i++) {
			if (items&#91;i&#93; == null) {
				items&#91;i&#93; = item;
				return;
			}
		}
	}

	// Loop through our array of products and add up the total value.
	// Go item by item adding the quantity on hand x its price.
	// Add that value to a running total accumulator variable.

	public double getTotalInvValue() {
		double sumOfInventory = 0.0;
		
		// Uses a condensed for loop which iterates the array of items.
		for (Product item : items) {
			// Make sure we have an item for the given position.
			if (item != null) {
				sumOfInventory += item.getItemValue();
			}
		}
		return sumOfInventory;
	}

	// Prints the inventory list including name, quantity, price, and total stock value for each item.
	public void printInventory() {
		System.out.println("Printing items in inventory...\n");

		boolean hasItems = false;

		for (Product item : items) {
			if (item != null) {
				hasItems = true;
				System.out.println(item.toString() + " Quantity: " + item.getQuantityOnHand() + " Value of Stock: " + formatter.format(item.getItemValue()));
			}
		}  

		// If no items were found, print a message saying the inventory is empty.
		if (!hasItems) { System.out.println("Inventory is empty at the moment.\n"); }
	}
}
&#91;/java&#93;

Here we have the code which carries out all these functions. Be sure to read through the in code comments to see what is going on here. As you can see we have a function called &#91;il&#93;getTotalInvValue()&#91;/il&#93; which loops through the products array (defined at the top as private) and adds up all their values by calling the individual product's &#91;il&#93;getItemValue()&#91;/il&#93; function. We also have a method called &#91;il&#93;addProduct()&#91;/il&#93; which takes a product class item as a parameter and adds it to the array of products. It does this by looping through the array looking for an empty slot. When it finds one, it inserts it into the array. 

Lastly, we have a &#91;il&#93;printInventory()&#91;/il&#93; function which moves through all the products and prints information about the items. Notice how I used the product's toString() function to get the name of the product and price, then use the methods to get the quantity and its inventory stock value. 

<h4>Part 3 - Inherit from Products class to make a special subclass.</h4>

Here I inherited from our products class in part 1 to make a specialized subclass called DVD. Things to note in this part of the project is that it asks you to override the products stock value to include some kind of restocking fee (usually 5%) and to create an extra feature that is not found in product. We use the DVD movie's year.

We simply create a new class and use the "extends" keyword to inherit from Product. We then put in a new variable for our movie year, add a mutator and accessor method for the year and override the getItemValue() function to include the restocking fee of 5% by multiplying the product's value (using a call to the base class by way of the "super" keyword) by 1.05 to give us the new product inventory value with the restocking fee. We also put in a function to get the restocking value in the case we want to print that out for the item.


// Inherited class DVD from the base class Product
// It is a product, but has the extra feature of having a year the movie was made.

public class DVD extends Product {
	// Holds the year the move was made
	private int movieyear;

	// Constructor, notice how it calls the constructor of Product first
	// Passing the base class its values to initialize the class BEFORE
	// setting this instance year variable.

	public DVD(int productId, String itemname, int quantityOnHand, double itemprice, int year) {
		// Pass on the values needed for creating the Product class first thing
		super(productId, itemname, quantityOnHand, itemprice);
		movieyear = year;
	}

	// In case they want to set the year manually
	public void setYear(int year) {
		movieyear = year;
	}

	// Get the year of this DVD product
	public int getYear() {
		return movieyear;
	}

	// Overrides getItemValue() in Product class by calling the base class version and
	// adding a 5% restocking fee on top
	public double getItemValue() {
		return super.getItemValue() * 1.05;
	} 

	// Simply gets the base class's value, and figures out the 5% restocking fee only
	public double getRestockingFee() {
		return super.getItemValue() * .05;
	}
}

One thing to note here is the constructor of this derived class. See how we pass on the parameters that are used to create the base class first (using the super keyword again) and then we use the new parameter to set the year variable? When deriving from a base object, make sure your constructor calls the base class constructor FIRST thing. It must be the first statement in the constructor. It needs to setup the Product class instance before it can derive this specialized object from it.

Again follow the in code comments to see what is going on and where everything is located. Make sure you understand this concept because it is VERY IMPORTANT in the world of object oriented programming and other languages. C++, VB.NET, C#, and other languages all use the same principle.

So the only thing left here is a driver program to show you how all three parts work here. Below is a nice little test program I wrote to test each part. I marked off each code segment to show you the functionality of the three separate parts here. Read through the code and you will see how everything works. I don’t think it needs much explaining.

// Import the format class to format values into currency format.
import java.text.DecimalFormat;

public class InventoryTest {
	static DecimalFormat formatter = new DecimalFormat("$##,###.00");

	public static void main(String args[]) {
		//*****************************************************************************
		// Code for Part1 of this project, creating and using the product class
		//*****************************************************************************
		// Create some products
		Product item1 = new Product(1, "Jacket", 3, 20.00);
		Product item2 = new Product(2, "Hackers (Blu Ray)", 10, 19.95);
		Product item3 = new Product(3, "BMW", 2, 45000.00);

		//*****************************************************************************
		// Code for Part2 of this project, creating and using the Inventory class
		//*****************************************************************************
	
		// Create an inventory item to store our products
		Inventory myWishList = new Inventory();

		// Let's show there is nothing in the inventory to start.
		myWishList.printInventory();

		// Now lets add the items we declared above.
		myWishList.addProduct(item1);
		myWishList.addProduct(item2);
		myWishList.addProduct(item3);

		// Print out the inventory
		myWishList.printInventory();

		// Print the total value of the inventory 
		// (after formatted using DecimalFormat class into dollars and cents)
		System.out.println("\nTotal value of inventory is: " + formatter.format(myWishList.getTotalInvValue()));
	

		//*****************************************************************************
		// Code for Part 3 of this project, specialized product inheritance
		// A DVD is a type of product, but has an extra feature, a year the movie was made.
		//*****************************************************************************

		// Create some DVD objects which are a specialized product classes
		DVD movie1 = new DVD(4, "Gladiator", 3, 24.99, 2000);
		DVD movie2 = new DVD(5, "Willy Wonka", 19, 23.55, 1971);

		// Lets show off the extra feature of year the movie was made
		System.out.println("\nYear Gladiator was made was: " + movie1.getYear());
		System.out.println("Year Willy Wonka was made was: " + movie2.getYear() + "\n");

		// Since DVD's are a type of product, they can go into the product array
		myWishList.addProduct(movie1);
		myWishList.addProduct(movie2);

		// Now when we print the list, you will notice that when the DVDs (only the DVDs) are listed
		// with their price, plus a 5% restocking fee as defined in the inherited class. 
		myWishList.printInventory();
	}
}

We create some products, create an inventory object, show you that the inventory is empty, add the products to the inventory object using our addProduct() method, show you that they were added and their stock value displayed along with the inventory total, create specialized DVD products, show you their year feature, add them to the inventory item (since the DVDs are a TYPE of product they can be added) and again printing out the final list.

That is all there is to it for the first three parts of this project. Some projects go into parts 4 and 5 and some do not. If I see an overwhelming desire to go into those parts for other students, I may add another blog entry for it. But for now, this should get you through the first couple weeks of learning a new language and working with this project.

Just remember that at DIC we be product and inventory wielding code ninjas! So keep the music blazing and the fingers dancing on the keyboards and thanks for reading! 🙂

About The Author

Martyr2 is the founder of the Coders Lexicon and author of the new ebooks "The Programmers Idea Book" and "Diagnosing the Problem" . He has been a programmer for over 20 years. He works for a hot application development company in Vancouver Canada which service some of the biggest tech companies in the world. He has won numerous awards for his mentoring in software development and contributes regularly to several communities around the web. He is an expert in numerous languages including .NET, PHP, C/C++, Java and more.