Getting data from another class in Java - java

public class Item {
/**
* Instance variables for this class
*/
private String itemName;
private int itemQuantity;
/**
* Contructor for this class
*/
public Item (String itemName, int itemQuantity) {
this.itemName = itemName;
this.itemQuantity = itemQuantity;
}
//setter and getter methods
public String getItemName () {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public int getItemQuantity () {
return itemQuantity;
}
public void setItemQuantity(int itemQuantity) {
this.itemQuantity = itemQuantity;
}
}
Ok..I already have the class for item. Now I have to write the CartItem class. The description that was given are as follows:
class CartItem{
/*
Objects of this class are used to hold items that the shopper purchases in the super market.
There are two attributes in this class, an item (an object created from the Item class) and a quantity (the number of that item that the shopper purchases). You have to write these two attributes. Note that one of the two will have a user defined data type.
*/
}
public class CartItem {
private Item item; //item from the item class
private int itemQuantity; //quantity how much shopper buys
public CartItem(Item itemName, int itemQuantity) {
this.getItem();
this.getQuantity();
}
public Item getItem() {
return item;
}
public void setItem(Item item) {
this.item = item;
}
public int getQuantity() {
return itemQuantity;
}
public void setQuantity(int quantity) {
this.itemQuantity = itemQuantity;
}
}
Just wondering if it's correct though.

No, it's not correct. Look at your constructor:
public CartItem(Item itemName, int itemQuantity) {
this.getItem();
this.getQuantity();
}
Here you're calling the getters and completely ignoring the values the caller has passed in. I don't think you want to do that... think about what the constructor needs to do in order to populate the newly constructed object...
(You should also consider making these classes immutable, but that's a slightly different matter.)

Few things.
1 Person may shop more than one Item so have List of Item
2 Constructor isn't correct, which should be
public CartItem(Item itemName, int itemQuantity) {
this.item = itemName;
this.itemQuantity = itemQuantity;
}

No it's not.
The constructor for CartItem just calls this.getItem() and this.getQuantity(). This will just call the methods, which will obviously return null, since the attributes are never initialized. It should be:
public CartItem(Item itemName, int itemQuantity) {
this.item = itemName;
this.itemQuantity = itemQUantity;
}
Another problem is that you add getters and setters for all the fields, without even knowing if those methods are necessary. Try to favor immutability, and only provide setters if they are absolutely necessary. I won't explain all the advantages of immutability, because it would be too early given what you already know. But a good rule of thumb is : don't add a method to a class if it's not used.

Related

Interfaces with abstract classes inheritance

Hey guys so Im new to Java and I'm having some trouble getting the hang of Interfaces, abstract classes etc.. So here I have this problem that I'm not sure to solve. Basically I have this one Interface that is susposed to be implemented by an abstract class, and that abstract class is susposed to "have" (not sure what the right term is ) a few other classes.Now I think I did the first part:
abstract class AbstractArticle implements Article {
final private String name;
final private double price;
final private String description;
AbstractArticle(String name,double price,String description) {
this.name = name;
this.price = price;
this.description = description;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
public String getDescription() {
return description;
}
class Accessory extends AbstractArticle {
final String instructionsForUse;
Accessory(String name, double price, String description, String instructionsForUse) {
super(name,price,description);
this.instructionsForUse = instructionsForUse;
}
public String getinstructionsForUse() {
return instructionsForUse;
}
class Merchandise implements Article {
final private int quantity;
Article article;
Merchandise(Article article) {
this.article = article;
quantity = 0;
}
Merchandise(Article article, int quantity) {
this.article = article;
this.quantity = quantity;
}
public int getQuantity() {
return quantity;
}
public Article getArticle() {
return article;
}
}
So firstly I needed to make an abstract class override the methods and use getters to get the values, than I needed to extend the abstract class use a super constructor to call the methods getName etc.. (hopefully I did that right) and now in the class merchandise I am susposde to have 2 constructors the first one (Article article) is susposded to set the value of quantity to 0 which doesnt make sense to me,shouldn't it be done in the second constructor?Now the problem is when I try to compile the Merchandise class i get an error saying I need to make the class abstract or override the method getDescription(). Is there any way I could avoid this?
Thanks!
It looks as though you're trying to implement a Decorator Pattern: Merchandise both is a Article and has a Article.
Your Merchandise class basically wraps an existing Article and adds a quantity field to it. The idea is that a Merchandise is an "Article with a quantity".
If you want to be able to treat a Merchandise instance as an Article, you need to define the methods declared in the Article interface. Presumably here the idea is just to have those methods return the same thing the wrapped Article instance returns, which you do with:
class Merchandise implements Article {
final private int quantity;
Article article;
Merchandise(Article article) {
this.article = article;
quantity = 0;
}
Merchandise(Article article, int quantity) {
this.article = article;
this.quantity = quantity;
}
public int getQuantity() {
return quantity;
}
#Override
public String getDescription() {
return article.getDescription();
}
// and similarly for any other methods declared in Article
// you might not really want (or need) this:
public Article getArticle() {
return article;
}
}

this(<params>) as shortcut in constructor?

I got a task that I need to reduce code in the constructor but when I do as in a given example it doesn't work :(
The source code looks so:
public class Item {
private Product product;
private int stock;
Item(Product product){
this.product=product;
this.stock=0;
}
Item(Product product, int stock){
this.product=product;
this.stock=stock;
}
I tried to write it in this way:
public class Item {
private Product product;
private int stock;
Item(Product product){
this(product, 0);
}
Item(Product product, int stock){
this(product, stock);
}
Could somebody tell me please what is wrong?
There's a circular reference in the second constructor, it's calling itself. Try this instead:
// this constructor is correctly defined
public Item(Product product, int stock) {
this.product = product;
this.stock = stock;
}
// this constructor calls the other one
public Item(Product product) {
this(product, 0);
}
Your second constructor is attempting to call itself, which makes no sense.
If your class had a super class having a constructor with the same parameters, you could write :
Item(Product product, int stock){
super(product,stock);
}
Since it doesn't, you should just assign the members of the instance in the second constructor :
Item(Product product, int stock){
this.product = product;
this.stock = stock;
}

Alternate for hash map

I have a set of objects of type "Part" and each Part is associated with quantity(a field that specifies number of units required of that particular Part ). Is there in way in java to store this data, other than hash map?
You can write a wrapper object that has two fields, Part and quantity:
public class PartWithQuantity
{
private Part part;
private int quantity;
public int getQuantity() { return quantity; }
public void setQuantity(int q) { quantity = q; }
public Part getPart() { return part; }
public void setPart(Part p) { part = p; }
}
You can also use a TreeMap if the concern is that the HashMap might use too much memory.
This can be done very easily by just storing the metadata into the arraylist.
You can take a class that contains one reference of part type and other(quantity) is int type. Then you can even store the instances of this new class into an arraylist. Do Remember ,you can access your information anytime from this arraylist by calling the object.
The simplest way to achieve this would be to modify the Part class and add the quantity field, along with its setter and getter.
Another option would be to use a wrapper object and store it in the Set.
I have created a convenience method called check() to easily identify the Part of interest:
public class PartExtended {
private Part part;
private int quantity;
public PartExtended(Part part, int quantity) {
this.part = part;
this.quantity = quantity;
}
public boolean check(Part part) {
return part.equals(this.part);
}
public Part getPart() {
return part;
}
public int getQuantity() {
return quantity;
}
}
To retrieve a Part's quantity, use a for loop:
Set<PartExtended> data = new HashSet<>();
data.add(new PartExtended(new Part(), 0));
for (PartExtended item : data) {
if (item.check(new Part())) {
int quantity = item.getQuantity();
}
}

Java: An Object Constructor Passing Same Object as Parameter

I have made an object called Transaction which I am passing in an ArrayQueue.
Here is the Transaction class constructors (I have the appropriate setter and getters too):
public class Transaction {
private int shares;
private int price;
public Transaction(int shares, int price) {
this.shares = shares;
this.price = price;
}
public Transaction(Object obj) {
shares = obj.getShares();
price = obj.getPrice();
}
}
In the second constructor there I am wanting a scenario where I can pass into it a different Transaction object that has been dequeue(ed) and get the info from that transaction and make it into a new transaction or possibly manipulate it before I put it back into the queue. But when I compile it does not like this.
Is this acceptable programming practice to pass a specific object into it's own object's constructor? Or is this even possible?
It's called copy-constructor and you should use public Transaction(Transaction obj) instead of Object and also provide getters:
public class Transaction {
private int shares;
private int price;
public Transaction(int shares, int price) {
this.shares = shares;
this.price = price;
}
public Transaction(Transaction obj) {
this(obj.getShares(), obj.getPrice()); // Call the constructor above with values from given Transaction
}
public int getShares(){
return shares;
}
public int getPrice(){
return price;
}
}
You need to specify the same type:
public Transaction(Transaction obj) {
shares = obj.getShares();
price = obj.getPrice();
}
Provided that you have defined getShares() and getPrice().
Yes this is entirely possible.
public Transaction(Transaction other){
shares = other.shares;
price = other.price;
}
You do not need to call their getters because privacy only applies to other classes.
Yes, you can do that but you will have to type cast the parameter
public Transaction(Object obj) {
Transaction myObj = (Transaction) obj;
shares = MyObj.getShares();
price = MyObj.getPrice();
}
for instance lets assume we have a class of Author with all the getters created
to pass another object as a parameter we use the following syntax
public Author(ClassName variable){
this(obj.getlength(), obj.getwidht())// height and width are the instance variable of the class.
}

Error: the method getId() is undefined for the type List<Product>

I have a method to create a list of objects of class
public List<Product> initProducts(){
List<Product> product = new ArrayList<Product>();
Product prod = new Product(product.getId(),product.getItemName(),product.getPrice(),product.getCount());
product.add(prod);
return product;
}
My Product class is:
public class Product {
int ItemCode;
String ItemName;
double UnitPrice;
int Count;
/**
* Initialise the fields of the item.
* #param Name The name of this member of product.
* #param id The number of this member of product.
* #param Price The price of this member of product.
*/
public Product(int id, String Name, double Price, int c)
{
ItemCode=id;
ItemName=Name;
UnitPrice=Price;
Count = c;
}
public int getId()
{
return this.ItemCode;
}
public String getItemName()
{
return this.ItemName;
}
public double getPrice()
{
return this.UnitPrice;
}
public int getCount()
{
return this.Count;
}
/**
* Print details about this members of product class to the text terminal.
*/
public void print()
{
System.out.println("ID: " + ItemCode);
System.out.println("Name: " + ItemName);
System.out.println("Staff Number: " +UnitPrice);
System.out.println("Office: " + Count);
}
}
I am getting an error that the method getId() is undefined for the type List<Product>, Similarly for other methods. Please help me out with this error.
Is my statement correct??
Product prod = new Product(product.getId(),product.getItemName(), product.getPrice(),
product.getCount());
product.add(prod);
product is a reference of List
List<Product> product = new ArrayList<Product>();
which doesn't have that method
product is reference to List object.
and List/ArrayList has no methosd named getId().
You have written getId() method for Prodct class , so you can call this method using ref to Product class object.
If you want to get any product object form list use get(int index) method of ArrayList.
eg.
Product prod = product.get(0);
String id= prod.getId();
I believe, the reason you are facing this issue is more due not following the code conventions, that any other.
Whenever you make a collection of any objects, the convention is to use plurals for reference names of the collection. And singular reference name of the Object itself.
You can find more details here.
Below is the re-written code with the code conventions being followed:
Method to create a list of objects of class Product:
public List<Product> initProducts(){
List<Product> products = new ArrayList<Product>();
Product product = new Product(products.getId(), products.getItemName(), products.getPrice(), products.getCount());
products.add(prod);
}
Product Class:
class Product {
int itemCode;
String itemName;
double unitPrice;
int count;
public Product(int itemCode, String itemName, double unitPrice, int count)
{
this.itemCode = itemCode;
this.itemName = itemName;
this.unitPrice = unitPrice;
this.count = count;
}
public int getId()
{
return this.itemCode;
}
public String getItemName()
{
return this.itemName;
}
public double getPrice()
{
return this.unitPrice;
}
public int getCount()
{
return this.count;
}
}
Now, it is easy to see, that the products Object (which is of the type List) will not have any methods name getId() or getCount(). Infact , these are methods of the Object contained in the List.
Following conventions will help you avoid, such hassles in futures.
Is my statement correct??
Product prod = new Product(product.getId(),product.getItemName(), product.getPrice(),
product.getCount());
product.add(prod);
NO this is incorrect. product is not an instance of class Product,rather it is an instance of List. List does not have any method called getId.
If you want to retrieve the elements from the list and use it to create another instance of you can do something like:
Product exisProd = product.get(0);
Product prod = new Product(exisProd .getId(),exisProd .getItemName(), exisProd .getPrice(),
exisProd .getCount());
But make sure that you have elements in the list, otherwise u may run into exception.
product.add(prod);

Categories