Using object of a class as parameter of other class - java

I am working on creating an ATM machine as a java project for one of my -very- Java Beginner's courses and I am confused about how to use an object of a class as a parameter of another class. I know how to use inheritance but in this case, User and BankAccount are at the same level and that also confuses me in this case.
This is my code so far :
BankAccount CLASS
package atm;
public class BankAccount {
public double balance;
private int accountNumber = 333220;
public String user;
public BankAccount(){
balance = 0;
}
public BankAccount(double balance, int accountNumber, User user){
this.balance = balance;
this.accountNumber = accountNumber;
this.user = user; // HERE, THE CONSOLE TELLS ME I CAN'T CONVERT USER TO STRING. USER HAS ONLY STRINGS AS PARAMETERS. DO I NEED TO CAST? HOW WOULD I DO IT?
}
public void accountNumber(){
accountNumber++;
}
public int getAccountNumber(){
return accountNumber;
}
public void deposit (double amount){
balance += amount;
}
public void withDraw(double amount) {
balance -= amount;
}
public double getBalance (){
return balance;
}
public void transfer( BankAccount other,double amount){
withDraw(amount);
other.deposit(amount);
}
}
user class :
package atm;
public class User {
public String name;
public String lastName;
private int dOB;
public User (String aName, String aLast){
name = aName;
lastName = aLast;
}
public String getName(){
return name;
}
public String getLastName(){
return lastName;
}
public int getDOB(){
return dOB;
}
public String getUniqueKey(int dOB){
String uniqueKey = name.substring(0,1) + name.substring(name.length() -1) + dOB + lastName.substring(0,1) + lastName.substring(lastName.length()-1);
return uniqueKey.toLowerCase();
}
}

Your user instance must have the data type User not String.
It must look like this:
public class BankAccount {
public double balance;
private int accountNumber = 333220;
public User user;
The detailed answer:
Java provides two types of data representation: primitive types and reference types.
Java has eight built-in data types, referred to as Java primitive types.
These eight data types represent the building blocks for Java objects because all Java objects are just a complex collection of these primitives. (short, int, double, etc..)
Reference types hold references to objects (instances of classes).
Unlike primitive types that hold their values in the memory where the variable is allocated, references don't hold the value of the object they refer to.
Instead, a reference points to an object by storing the memory address where the object is located.
Instance variables can be both reference type and primitive type in your example you are using a reference type that represent the account property "User".

Well what you're trying to do is giving a String object reference a User object, that's why "THE CONSOLE TELLS ME I CAN'T CONVERT USER TO STRING" happens.
what you should do is simply replace this line: public String user;
with this: public User user; so the object reference matches the object type itself.

Related

Java nested POJO update based on dot annotation

I have a nested POJO structure defined something like this,
public class Employee {
private String id;
private Personal personal;
private Official official;
}
public class Personal {
private String fName;
private String lName;
private String address;
}
public class Official {
private boolean active;
private Salary salary;
}
public class Salary {
private double hourly;
private double monthly;
private double yearly;
}
I get updates from a service with dot annotaion on what value changed, for ex,
id change --> id=100
address change --> personal.address=123 Main Street
hourly salary change --> official.salary.hourly=100
This POJO structure could be 3-4 level deeps. I need to look for this incoming change value and update the corresponding value in POJO. What's the best way of doing it?
If you would like to create Java objects that allows you to edit fields. You can specify your object fields with the public/default/protected access modifiers. This will enable you to get and set fields such as personal.address or official.salary.hours
This approach is typically frowned upon as the object is no longer encapsulated and any calling methods are welcome to manipulate the object. If these fields are not encapsulated with getters and setters, your object is no longer a POJO.
public provides access from any anywhere.
default provides access from any package
protected provides access from package or subclass.
public class Employee {
public String id;
public Personal personal;
public Official official;
}
public class Personal {
public String fName;
public String lName;
public String address;
}
Here's a quick approach using reflection to set fields dynamically. It surely isn't and can't be clean. If I were you, I would use a scripting engine for that (assuming it's safe to do so).
private static void setValueAt(Object target, String path, String value)
throws Exception {
String[] fields = path.split("\\.");
if (fields.length > 1) {
setValueAt(readField(target, fields[0]),
path.substring(path.indexOf('.') + 1), value);
return;
}
Field f = target.getClass()
.getDeclaredField(path);
f.setAccessible(true);
f.set(target, parse(value, f.getType())); // cast or convert value first
}
//Example code for converting strings to primitives
private static Object parse(String value, Class<?> type) {
if (String.class.equals(type)) {
return value;
} else if (double.class.equals(type) || Double.class.equals(type)) {
return Long.parseLong(value);
} else if (boolean.class.equals(type) || Boolean.class.equals(type)) {
return Boolean.valueOf(value);
}
return value;// ?
}
private static Object readField(Object from, String field) throws Exception {
Field f = from.getClass()
.getDeclaredField(field);
f.setAccessible(true);
return f.get(from);
}
Just be aware that there's a lot to improve in this code (exception handling, null checks, etc.), although it seems to achieve what you're looking for (split your input on = to call setValueAt()):
Employee e = new Employee();
e.setOfficial(new Official());
e.setPersonal(new Personal());
e.getOfficial().setSalary(new Salary());
ObjectMapper mapper = new ObjectMapper();
setValueAt(e, "id", "123");
// {"id":"123","personal":{},"official":{"active":false,"salary":{"hourly":0.0,"monthly":0.0,"yearly":0.0}}}
setValueAt(e, "personal.address", "123 Main Street");
// {"id":"123","personal":{"address":"123 Main Street"},"official":{"active":false,"salary":{"hourly":0.0,"monthly":0.0,"yearly":0.0}}}
setValueAt(e, "official.salary.hourly", "100");
// {"id":"123","personal":{"address":"123 Main Street"},"official":{"active":false,"salary":{"hourly":100.0,"monthly":0.0,"yearly":0.0}}}

How to transfer input data from a private void GUI to an ArrayList in a java class?

I need help with a specific problem in my class project. The goal of the project is to create a program in which you can register how much shares you own. Information that's required is the company name, how many shares you own and their respective value. I created a GUI class and a class where the information is transferred to. The input comes from a private void. I'm having trouble finding a way to transfer the input from the private void to a an arraylist in a class outside it.
Here is how I initialized the arraylist in the GUI class.
public class GUISharePortfolio_1 extends javax.swing.JFrame {
ArrayList<SharePackage.Share> Package = new ArrayList<SharePackage.Share>();
Next is how I get the company name, number of shares and their value from the GUI. Since it is a private void I have to transfer that information to the SharePackage class.
private void CreatePortfolioButtonActionPerformed(java.awt.event.ActionEvent evt) {
String name;
double number;
double value;
name = CompanyNameField.getText();
number = Double.parseDouble(NumberOfSharesField.getText());
value = Double.parseDouble(ValueOfShareField.getText());
Package.CompanyName(name);
Package.NumberOfShares(number);
Package.ValueOfShare(value);
}
I'm getting an error saying "cannot find symbol" under the CompanyName, NumberOfShares and ValueOfShare.
The public class to which the info should be transferred is this:
package shareportfolio;
import java.util.ArrayList;
public class SharePackage
{
private ArrayList<Share> Package = new ArrayList<Share>();
public class Share
{
private String companyname;
private double numberofshares;
private double valueofshare;
Share(String companyname, double numberofshares, double valueofshare)
{
this.companyname = companyname;
this.numberofshares = numberofshares;
this.valueofshare = valueofshare;
}
public void setCompanyName(String name)
{
companyname = name;
}
public String getCompanyName()
{
return(companyname);
}
public void setNumberOfShares(double number)
{
numberofshares = number;
}
public double getNumberOfShares()
{
return(numberofshares);
}
public void setValueOfShare(double value)
{
valueofshare = value;
}
public double getValueOfShare()
{
return(valueofshare);
}
}
}
I would appreciate any help very much.
You have a field named Package, who's type is ArrayList. ArrayList doesn't have a method called CompanyName. What you're probably trying to do is something like:
Package.add(new SharePackage.Share(companyname, numberofshares, valueofshares));
You have two such fields named 'Package', so not sure which one you're trying to add to. Maybe you're under the impression the fields are somehow the same one. They are not.
BTW: Definitely learn Java coding style before submitting this to anyone. You are naming fields with UpperCamelCase which makes it very difficult for a java programmer to read your code.
user1207705 that was the answer. I modified it to:
String name;
double number;
double value;
name = CompanyNameField.getText();
number = Double.parseDouble(NumberOfSharesField.getText());
value = Double.parseDouble(ValueOfShareField.getText());
Package.add(new SharePackage.Share(name, number, value));
Thank you for your help and I will work on Java coding style.

Method override returns null

I'm newbie in Java. So question might sound simple, but I'm stuck and can not figure out why this code returns null and 0.0 ?
file: Transport.java
public class Transport {
private String name;
private double price;
public Transport(String name, double price) {
this.name = name;
this.price = price;
}
public String carName() {
return name;
}
public double carPrice(){
return price;
}
}
file: Car.java
public class Car extends Transport{
protected String name;
protected double price;
public Car(String name, double price) {
super(name, price);
}
#Override
public String carName(){
return name;
}
#Override
public double carPrice(){
return price * 1.5;
}
}
file: Main.java
public class Main {
public static void main(String[] args) {
Car c = new Car("CarBrand", 1000);
System.out.println("Name: " + c.carName());
System.out.println("Price: " + c.carPrice());
}
}
Output
Name: null
Price: 0.0
You've declared separate name and price variables in Car, and never assigned a value to them - they're not the same as the name and price variables declared (and initialized) in Transport. So you're seeing the default values for String and double, basically. Get rid of those extra variables in Car, and use super.carPrice() to get the original price from Transport:
public class Car extends Transport {
public Car(String name, double price) {
super(name, price);
}
#Override
public double carPrice(){
return super.carPrice() * 1.5;
}
}
Note that there's no need to override carName() at all unless you really want it to change behaviour.
I'd also suggest changing carName() and carPrice() to getName() and getPrice() to be more idiomatic.
You are passing both the values to parent class Transport through super(). So
Car c = new Car("CarBrand", 1000);
will eventually set
Transport class attributes name & price.
You dont need to declare both the attributes in Car class. Car will have both attributes implicitly through inheritance. Here you are creating separate attributes for Car.
The problem is that you have two different variables for name, one in Car and one in Transport. c.carName() returns Car.name which has not been initialized.
If your car class is the one below, it will work
public class Car extends Transport {
public Car(String name, double price) {
super(name, price);
}
#Override
public double carPrice(){
return price * 1.5;
}
}
the same goes for the variable price
The derived class Car is hiding the instance variables of class Transport .So although you are inheriting the correctly initialized data members from Transport class ,but the Car class instance variables initilized to their default values are getting returned from Car class methods
When you create the 'c' object of type Car, you assign values only for 'name' and 'price' variables of class Transport (because in your constructor you call super(name, price) that will call the constructor from your Parent class).
Here: c.carName() you call the method from your Car class (because is marked as #Override) and this one returns the value of the 'name' variable from class Car. And this variable in your case, is null because you didn't assign any value for it yet.
You assigned the value "CarBrand" for 'name' variable of type Transport.
The same for 'price' variable.
The use of super will return the values which you already stored in the parent class by calling the constructor super(name, price), the use of super followed by dot notation will access the parent class method. So super.carPrice() will return the value stored in the parent class.
Also, #Override annotation should only used to change an existing method from the parent class with a new functionality in the child class with out changing the name. So in case of the #Overide for carname() you need to call the super.carname() because you are returning the value from the parent class.
In short, The reason why you are getting null and 0.0 because you are accessing the child class values when you should be accessing the parent class values.
public class Car extends Transport{
protected String name;
protected double price;
public Car(String name, double price) {
super(name, price);
}
#Override
public String carName(){
return name;
}
#Override
public double carPrice(){
return price * 1.5;
}
}
Your class should be
public class Car extends Transport{
public Car(String name, double price) {
super(name, price);
}
public String getName(){
return super.carName();
}
#Override
public double carPrice(){
return super.carPrice()* 1.5;
}
}
your main class should now be
public class Main {
public static void main(String[] args) {
Car c = new Car("CarBrand", 1000);
System.out.println("Name: " + c.getName());
System.out.println("Price: " + c.carPrice());
}
}

Creating a simple stock inventory program - 2nd attempt

I have asked this question before and followed the feedback as best as I could but I am still having one problem with storing the info that the user enters into the array.
Here is the first attempt:
OOP Java: Creating a stock inventory program
So I need to have in total three classes(That's required). The Stock, stock inventory and then the user interface. The purpose of this program is to ask the user to input the company's name, stock rating, price and the number of shares. Of course, I then have to do other things. I think I am okay with the rest, the problem is the stockInterface, the last bit of code that I post below.
public class Stock {
private String companyName;
private String stockRating;
private int price;
private int numberOfShares;
public String getCompanyName() {
return companyName;
}
public int getStockRating() {
return stockRating;
}
public String getPrice() {
return price;
}
public int getNumberOfShares() {
return numberOfShares;
}
public Stock(String companyName, String stockRating, int price, int numberOfShares) {
super();
this.companyName = companyName;
this.stockRating = stockRating;
this.price = price;
this.numberOfShares = numberOfShares;
}
import java.util.*;
public class StockInvetory {
private static final int INVENTORY_SIZE = 12;
private Stock [] stocks;
public StockInvetory() {
stocks = new Stock [INVENTORY_SIZE];
}
public class StockInterface() {
private static StockInventory stockPortfolio;
public static void main (String [] args){
System.out.println ("Stock's name:");
String stockName = console.next();
System.out.println ("Stock's rating");
String stockRating= console.next();
System.out.println ("Stock's price:");
int stockPrice = console.nextInt();
System.out.println ("Numbers of shares: ");
int numberShares= console.nextInt();
stockPortfolio [0]= new Stock(stockName, stockRatings, stockPrice, numberShares);
}
This piece of code doesn't work.
stockPortfolio [0]= new Stock(stockName, stockRatings, stockPrice, numberShares)
Can somebody please show me the proper way to store the info into the array? Thank you very much.
Lots of compile errors...
You have defined stockRating as a String but yet return it as an int:
public int getStockRating() {
return stockRating;
}
The same is true for price.
You have extra parenthesis here:
public class StockInterface() {
^
Also in StockInventory, there are multiple statements in the class block They belong in a method.
console is not instantiated.
stockPortfolio is assigned as an array entry, yet it is a single object, and assigned to the Stock which is not a matching type.
So you've declared the stockPortfolio as an instance of StockInventory. StockInventory is a class not an array, so you can't use stockPortfolio [0] = ... because stockPortfolio is an instance of the class. You have a private member in StockInventory that is an array of Stock class instances. What you need is an accessor method to be able to manipulate it. So change StockInventory as follows:
public class StockInvetory {
/*
All the code you have now ...
*/
public Stock [] getStocks(){
return stocks;
}
public setStocks(Stock [] value){
//maybe some checking here ...
stocks = value;
}
}
Now just a slight change in using the class. You need to use the accessor methods as follows:
public class StockInterface {
/*
What you have just the following line changes ...
*/
stockPortfolio.getStocks()[0] = new Stock(stockName, stockRatings, stockPrice, numberShares);
}
I am assuming you are happy with the way you are initializing the array and that you have decided arrays are better than more dynamic data structures in collections for your specific project. If this is not true have a look at Java Collections they may bring you more joy.

Return a string and int

How do i return a string and an integer? say i wanted to return
students name which is an string and their mark which is an integer.
I cant do mark=mark+element+(element2+name); that creates an incompatible type.
My suggestion in this type of situation is to create a new class that holds this information. Name it for example StudentMark.
class StudentMark {
private final String name;
private final int mark;
public StudentMark(String name, int mark) {
this.name = name;
this.mark = mark;
}
public String getName() { return name; }
public int getMark() { return mark; }
}
Then in your method that has both the name and mark where you want to return, just do like so.
return new StudentMark("Samuel", 3.2);
Here you can also add any other interesting methods that you might need.
Create a class Student and return a student
class Student{
private String name;
private int mark;
//assessor+ contructors
}
you'll need to define a class for it. the class should have two attributes: a string and an int
Define a class that contains both values and return an object of that class.
create A class with priavte variables for name and marks. and override toString() method.
public class Student{
private int marks;
private String name;
//provde setters and getters for marks and name
public String toString(){
return getName()+getMarks();
}
}
In your Student class, you can have a method:
public String printNameAndGrade() {
return "Name: " + this.getName() + "\n " + "Grade: " + this.getGrade();
}
and then call it with a Student object reference:
Student st1 = new Student("Gabe Logan", 97);
System.out.println(st1.printNameAndGrade()); //use `println` method to display it.
You can use a two element Array or List and put the values in there. Unfortunately this looses all type Information.
You can use a Map which keeps the type information, but might be confusing because you would expect an arbitrary number of entries.
The cleanest option is to create a simple class with the two elements.

Categories

Resources