Passing objects subclass type - java

I am working with a function that takes a class type as parameter:
I am trying to pass getSpans() the specific subclass of the Object "type."
Spannable ss;
Object type;
int start;
int end;
//Assume above variables properly initialized.
....
//getSpans(int start, int end, Class<T> type)
ss.getSpans(start, end, ???);

Yes, just use type.class. It will return the Class object of the type variable. Also try type.getClass().class.
http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html
Better use the 2nd example.

You can achieve this functionality without resorting to a series of instanceof's by using the Strategy Pattern. Here is an example implementation that calculates shipping costs using different providers without actually having to know what provider type is used.
public enum ShippingMethod {
FIRST_CLASS {
public double getShippingCost(double weightInPounds, double distanceInMiles) {
// Calculate the shipping cost based on USPS First class mail table
}
},
FED_EX {
public double getShippingCost(double weightInPounds, double distanceInMiles) {
// Calculate the shipping cost based on FedEx shipping
}
},
UPS {
public double getShippingCost(double weightInPounds, double distanceInMiles) {
// Calculate the shipping cost based on UPS table
}
};
public abstract double getShippingCost(double weightInPounds, double distanceInMiles);
};
public class ShippingInfo {
private Address address;
private ShippingMethod shippingMethod = ShippingMethod.FIRST_CLASS;
public Address getAddress() {
return this.address;
}
public double getShippingCost(double weightInPounds, double distanceInMiles) {
return shippingMethod.getShippingCost(weightInPounds, distanceInMiles);
}
}
More info on the Strategy Pattern and full example.

Related

How to create an object while using enum in a class?

I previously have the variable availability stored in a double which is present inside a class named wrapper as below -
public final class Wrapper {
private final double availability;
Wrapper(){
this.availability = 2;
}
public Wrapper(final double availability){
this.availability = availability;
}
public double availability (){ // Need a confirmation if this is a getter ?
return this.availability;
}
}
Now, I have to change the scenario a bit by making availability as an object.Reason being - Now we want availability per region unlike the above case.Also, we need to use that availability object inside the wrapper class now.
Here is what I'm trying to do -
public final class Availability {
public enum Region {
US,
UK,
EU;
private final double availability;
Region () {
this.availability = 2;
}
Region (double availability) {
this.availability = availability ;
}
}
I'm supposed to use the Availability object inside wrapper class as wrapper class object is being used in other places which previously used to take argument (Availability). Now I don't want to break that workflow. Also I'm a bit confused a bit regarding creation of object for Availability class as I'm using an enum. Can anyone please help me with this. Thanks in advance!
Per my understanding, you do not need class Availability.
Define Region.java file as having public enum Region, then you can have that constructor along with adding a missing getter.
public enum Region {
US(2),
UK(2),
EU(2);
private final double availability;
Region (double availability) {
this.availability = availability ;
}
public getAvailability() {
return this.availability;
}
}
Then Wrapper can accept Region instance instead, and access .getAvailability() method of it.
public final class Wrapper {
private final Region region;
public Wrapper(Region region){
this.region = region;
}
public double getAvailability() {
return this.region.getAvailability();
}
e.g. System.out.print(new Wrapper(Region.US).getAvailability());

Using object of a class as parameter of other class

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.

I have created two classes, when I entered negative quantity and negative price it does not set to be "0" and "0.0"

I have created two classes, when I entered negative quantity and negative price it does not set to be "0" and "0.0" respectively as I assigned condition in setitmprch(int itmprch) and setitmprch(int itmprch) methods. Kindly tell where I did a mistake.
public class INVOICE {
private String pn;
private String pdscp;
private int itmprch;
private double prpitm;
private double amount;
public INVOICE(String pn, String pdscp, int itmprch, double prpitm ){
this.pn=pn;
this.pdscp=pdscp;
this.itmprch=itmprch;
this.prpitm=prpitm;
}
public void setpn(String pn){
this.pn=pn;
}
public void setpdscp(String pdscp){
this.pdscp=pdscp;
}
public void setitmprch(int itmprch){
if (itmprch < 0)
itmprch=0;
}
public void setprpitm(double prpitm){
if(prpitm > 0.0)
this.prpitm=prpitm;
else if(prpitm < 0.0)
this.prpitm=0.0;
}
public String getpn(){
return pn;
}
public String getpdscp(){
return pdscp;
}
public int getitmprch(){
return itmprch;
}
public double getprpitm(){
return prpitm;
}
public double getInvoiceAmount(){
amount= getitmprch()*getprpitm();
return amount;
}
}
public class INVOICETEST {
public static void main(String[] args) {
// TODO code application logic here
INVOICE in= new INVOICE("Mercedez","Arw 777",-3,-2.0);
System.out.printf("Part number is: %s\n",in.getpn());
System.out.printf("Part decription is: %s\n", in.getpdscp());
System.out.printf("Item purchased: %s\n",in.getitmprch());
System.out.printf("Price per item is: %s\n",in.getprpitm());
System.out.printf("Total amount is: %s\n",in.getInvoiceAmount());
}
}
You are assigning values to the method parameters, which will be lost as soon as you exit your method. Add this.itmprch = itmprch to your setitmprch method. Also have a look at some Java programming guidelines to improve code readability.
public void setitmprch(int itmprch){
if (itmprch < 0)
itmprch=0;
this.itmprch = itmprch;
}
Also your constructor should call the setter methods instead of assign values directly. It would look something like this:
public INVOICE(String pn, String pdscp, int itmprch, double prpitm ){
setpn(pn);
setpdscp(pdscp);
setitmprch(itmprch);
setprpitm(prpitm);
}
Don't use all caps for class names.
Use more descriptive variable names - my eyes are bleeding looking at this and it takes 10x longer to understand than it should.
Use automatic properties rather than having private backing fields and void methods to set/get.
Use property for simple calculations such as working out invoice amount.
Don't asssign to private variable then return said variable.
Use unit tests to test your logic rather than a main method. What happens when your code grows, how are you going to test it all using one entry point?
Don't use protected keywords like in for variable names (in your main function).
The following code is in C#, but it should be easily transcribable to Java. Do some research on unit testing frameworks for Java and try and incorporate that into your workflow.
public class Invoice
{
public string ModelName { get; set; }
public double Price { get; set; }
public double Amount { get; set; }
public double InvoiceAmount => Price * Amount;
}
[TestClass]
public class InvoiceTest
{
[TestMethod]
public void TestInvoiceAmount()
{
// Arrange
var testInvoice = new Invoice()
{
ModelName = "Audi R8",
Price = 5000.0,
Amount = 1
};
// Act
double invoiceAmount = testInvoice.InvoiceAmount;
// Assert
Assert.IsTrue(invoiceAmount == 5000.0);
}
}

How do I set a field to equal another field in another class

I have the following:
Class 1:
public class SellProduct
{
private int productCost;
public SellProduct(int productCost)
{
this.productCost = productCost;
}
public int getProductCost()
{
return productCost;
}
}
This class will set how much a product costs.
Class 2:
public class SalesOfTheYear
{
private int totalIncome;
SellProduct sellProduct;
public SalesOfTheYear()
{
totalIncome = 0;
}
public void cashOut()
{
totalIncome = sellProduct.getProductCost() + totalIncome;
}
public int getSalesOfTheYear()
{
return totalIncome;
}
}
Now what I want is that class two to take how much the products cost and then set it to the totalIncome field. And of course to keep it's value at the same time and not replace it with a new totalIncome value.
However, every time I run cashout it sends a java.lang.NullPointerException. Does this mean I have to create an object of class sellPoduct?
And if do I would have to supply it with a parameter does that mean that whatever I supply it with a parameter so will it always be the productCost?
Yes, it makes sense to pass product cost to cashOut() method and add it into totalIncome rather than storing reference of SellProduct itself. It will look like this:
public void cashOut(int cost){
totalIncome += cost;
}
Also, we don't need default constructor in SalesOfTheYear class as int literals are assigned default values (0 in this case) when object is created.
Yes in Java whenever you have your own classes like SellProduct you will have to initialise it with:
SellProduct sellProduct = new SellProduct(xxx);
with xxx being an integer in your case
If you give it the number 20 then your totalIncome will increase with 20 every time you run cashOut()
To update the totalIncome field in a SalesOfTheYear instance, you need to transmit all required SellProduct instances to SalesOfTheYear .
Either, you have all the instances and you provide them in one time, either you may provide instance by instance.
public class SalesOfTheYear
{
private int totalIncome;
SellProduct sellProduct;
public SalesOfTheYear()
{
totalIncome = 0;
}
public void cashOut(SellProduct sellProduct)
{
totalIncome = sellProduct.getProductCost() + totalIncome;
}
public void cashOut(List<SellProduct> sellProducts)
{
for (SellProduct product : sellProducts){
cashOut(product);
}
}
public int getSalesOfTheYear()
{
return totalIncome;
}
}
How to use :
SalesOfTheYear salesOfTheYear = new SalesOfTheYear();
salesOfTheYear.cashOut(new SellProduct(500));
salesOfTheYear.cashOut(new SellProduct(100));
int totalSale = salesOfTheYear.getSalesOfTheYear();

base and subclass constructor issues

I have been experimenting with Classes in Java over the last few days, learning about them from "TheNewBoston" on youtube and from the java docs.
I have created the following scenario and seek your guys' (girls too) professional criticism and in depth knowledge regarding a few questions I have.
There are two classes, person and person_financial, a base class and sub class respectively.
person class:
public class person {
private String name;
private String sex;
private int age;
private double height;
private double weight;
private double intelligence;
// person constructor arguments order: name, height, weight, age, sex, intelligence
public person(){
this("noname",0,0,0,"undefined",5);
}
public person(String n){
this(n,0,0,0,"undefined",5);
}
public person(String n, double h){
this(n,h,0,0,"undefined",5);
}
public person(String n, double h, double w){
this(n,h,w,0,"undefined",5);
}
public person(String n, double h, double w, int a){
this(n,h,w,a,"undefined",5);
}
public person(String n, double h, double w, int a, String s){
this(n, h, w, a, filterSex(s), 5);
}
public person(String n, double h, double w, int a, String s, double i){
name = n;
height = h;
weight = w;
age = a;
sex = filterSex(s);
intelligence = i;
}
public void setName(String n){
name = n;
}
public void setHeight(double h){
height = h;
}
public void setWeight(double w){
weight = w;
}
public void setAge(int a){
age = a;
}
public void setSex(String s){
sex = filterSex(s);
}
public void setIntel(double i){
intelligence = i;
}
public String getName(){
return name;
}
public double getHeight(){
return height;
}
public double getWeight(){
return weight;
}
public int getAge(){
return age;
}
public String getSex(){
return sex;
}
public double getIntel(){
return intelligence;
}
public String getInfo(){
return String.format("Name: %s,\nSex: %s,\nAge: %d,\nIntelligence: %.2f,"
+ "\nHeight: %.2f,\nWeight: %.2f\n", name, sex, age,
intelligence, height, weight);
}
private static String filterSex(String s){
return ((s.equalsIgnoreCase("male") ||
s.equalsIgnoreCase("female")) ? s : "undefined");
}
}
person_financial class:
public class person_financial extends person {
private double monies = 0;
public void definePerson(String n, int a, String s, double i, double h, double w){
setName(n);
setAge(a);
setSex(s);
setIntel(i);
setHeight(h);
setWeight(w);
}
public person_financial() {
this(0);
}
public person_financial(double m) {
monies = m;
}
public void depositMonies(double m) {
monies += m;
}
public void withdrawlMonies(double m) {
if (m <= monies) {
monies -= m;
}
}
public double getBalance() {
return monies;
}
}
and then in the main class I have this:
public class Main {
public static void main(String[] args) {
person p1 = new person("I have no Name", 180, 72, 38, "Alien", 7.2);
System.out.println(p1.getName());
person_financial pf1 = new person_financial(100.00);
pf1.depositMonies(50.02);
System.out.printf("%s has %.2f monies.\n", pf1.getName(), pf1.getBalance());
pf1.definePerson("some_name", 42, "male", 10, 180, 72);
System.out.println(pf1.getInfo());
}
}
in the person_financial class, I have made a method called "definePerson()" which I use to define all the characteristics that would otherwise have been defined from the 'person()' constructor from the 'person' class. I'm sure there is a more professional way for assigning values to variables in a base class from a sub class, I just dont know of any...
Also, is there any way to call the constructor from the "person" class to define characteristics for 'pf1'? rather than having to, for example, manually set each attribute, i.e. pf1.setName("something"); , or pf1.setAge(1000000); etc... or have a method do it for me, as in 'definePerson()'.
Any help is much appreciated,
Thanks =).
You use the super() call to call the constructor of the parent class. It has to be the first call in the constructor of the derived class, but you call it (and pass in arguments) like any other function and it will call the constructor that way.
It's common to declare a class 'abstract' to prevent creation of generic objects - based on your usage-code at the bottom you seem not to want that and that's fine. Just remember that you can declare declare a class abstract.
The best way to use class hierarchy is to ensure that (buzzword alert) any class in a useful hierarchy should be declarable as anythin in the hierarchy (i.e. you should be able to access any methods in your concrete object from the base-class (person in this case).
Your financial_person object extends person, but the ideal is to have a class that you can declare at a high level and call methods polymorphically. Consider for a minute that all people are able to draw and deposit money (different from your classes, but bear with me for a minute).
drawMoney method would exist in person, but be marked abstract - forcing the subclasses financial_person and regular_person to implement draw_money, deposit_money etc.
each class would have an implementation that suits their reality (financial person would have access to all kinds of special accounts, discounts etc., and regular_person would have a simpler set of - but still the same external behavior).
Then you could declare like this:
Person finPerson = new FinancialPerson(... etc.);
Person regPerson = new RegularPerson(....etc);
note now that you are able to do this code below:
finPerson.drawCash(12300.0);
regperson.drawCase(100.0);
The identical behavior.
You could have a List of thousands of people, and would not have to do if-then-else or switch statements to execute the finer-tuned behaviors of each.
The acid-test for class-hierarchy is this: "my (sub-class) really 'a kind of' (superclass)?"
In other words, "does my subclass have behaviors of the superclass?"
If not, you should think carefully about class hierarchy. There's a buzzword for this : Liskov Substitution Principle, and I cannot do a better job of this than Robert. C. Martin - one of the software-design gurus:
http://www.objectmentor.com/resources/articles/lsp.pdf
In this article he shows what happens when you have inadvisable hierarchy, using the "a square is a kind-of rectangle" example.
Google "template method pattern" for a summary of another aspect of effectively using inheritance. You will see that it is much more powerful than the simple inheritance that most people dismiss it as being.
Also remember that no single pattern is a silver-bullet for everything. Some people will call class-hierarchy evil and tell you to use interfaces only; others will say the reverse. There are choices to make, and sometimes they will not be obvious.
There are many pitfalls, and missing LSP is just one of them. Others are (examples only) overriding concrete methods, having concrete classes not marked final, enabling mutability of "identifying" fields (eg fields used in equals/hashcode, etc.) Imagine if "customer" objects at bank allowed resetting of first-name, or account-number at runtime, once these fields were already set).
My answer is more generally related to OO design, inheritance etc. than specific coding questions - hope it's of some use to you.

Categories

Resources