I need to inherit an instance method from the superclass but I am stuck.
public class Pay
private float hours;
private float rate;
private int hrsStr;
float gross;
double tax;
public void calc_Payroll()
{
if (hrsStr != 0)
gross = hrsStr + ((hours - hrsStr) * 1.33f) * rate;
else
gross = hours * rate;
}
public void tax(double a)
{
if (gross <= 399.99)
tax = .92;
else
if (gross <= 899.99)
tax = .88;
else
tax = .84;
}
this is the part of the super class, i need have the same method signature(???) was well as invoke tax(double a) and calc_payroll()
this is what i had for the sub class but it wasn't working.
public class Payroll extends Pay
{
float net;
void calc_payroll()
{
float finaltax = (float) tax;
net = gross * finaltax;
}
}
Your void calc_payroll() in your sub class does not either override or invoke the super class method.
If you want to override the method in your base class, the method signature must be the same. Use the #override annotation for clarity.
#override
public void calc_Payroll(float a, float b, int c, float d)
{
}
If your new method has a different signature, then you can call the super class method using....
void calc_payroll()
{
super.calc_Payroll( ... );
}
Depends what behaviour you require in your new method and if you want to invoke the behaviour in the super class method.
Related
I'm working on a tiny exercise java program that calculates circle and square (classes) area, that implements surface (interface) which has a method called area(). A requirement is that I have to implement a class called SumArea that has a generic method called calcArea() that receives Circle circ[] and Square square[] arrays and executes area calculation.
Program structure:
-> UseSumArea.java (main method)
-> Surface.java (interface)
-> Square.java (class that implements Surface.java)
-> Circle.java (class that implements Surface.java)
-> SumArea.java (class that executes calcArea() method)
UseSumArea.java
public class UseSumArea {
public static void main(String[] args) {
Square square[] = { new Square(2.0), new Square(5.0) };
Circle circ[] = { new Circle(3.0), new Circle(2.0) };
Surface surf[] = new Surface[square.length + circ.length];
surf[0] = square[0];
surf[1] = square[1];
surf[2] = circ[0];
surf[3] = circ[1];
SumArea sum = new SumArea();
System.out.println("Square's sum area = " + sum.calcArea(square));
System.out.println("Circle's sum area = " + sum.calcArea(circ));
System.out.println("Surface's sum area = " + sum.calcArea(surf));
}
}
Surface.java
public interface Surface {
public double area();
}
Square.java
public class Square implements Surface {
private double area;
private double side;
public Square(double l) {
this.side = l;
area();
}
#Override
public double area() {
return this.area = (this.side)*(this.side);
}
public double getArea() {
return area;
}
public void setArea(double area) {
this.area = area;
}
public double getSide() {
return side;
}
public void setSide(double side) {
this.side = side;
}
}
Circle.java
public class Circle implements Surface {
private double area;
private double radius;
public Circle (double r) {
this.radius = r;
area();
}
#Override
public double area() {
return area = (((this.radius)*(this.radius))*(Math.PI));
}
public double getRadius() {
return radius;
}
public void setRadius(double raio) {
this.raio = raio;
}
public double getArea() {
return area;
}
public void setArea(double area) {
this.area = area;
}
}
SumArea.java
public class SumArea {
private double area;
public <T> double calcArea(T[] t) { //generic method that receives Square and Circle arrays
double arrayArea = 0;
for (T a : t) {
arrayArea = arrayArea+(a.area());
}
return this.area = arrayArea;
}
}
My doubt is over this SumArea's code snippet:
arrayArea= arrayArea+(a.area());
How can I access the area() method of each Circle and Square objects inside this generic method?
You need to bound the type variable:
public <T extends Surface> double calcArea(T[] t) {
or just declare the parameter as an array of Surfaces:
public double calcArea(Surface[] t) {
Note that the latter is preferable because generics and arrays don't play very nicely together. If you were to need to have a type variable for other reasons, it would be advisable to change to a Collection, or similar:
public <T extends Surface> double calcArea(Collection<T> t) {
(And, as a minor matter of preference, I would use S rather than T to name a type variable which extends Surface)
Since the problem in regard to generic types is already addressed by Andy Turner, I just want to add a suggestion related to the class design.
I think there is a bit of redundancy in how these classes were designed. You need to create an instance of SumArea in order to do the calculation. And the result of the last of the last calcArea() method call will be stored in this object (let's assume that this calculation is far more complex and CPU-consuming).
But do we really need to store somewhere else the value is already returned by the method? In this case, the idea to cash the history of calculations (as a single variable or as a collection of values) doesn't seem to be useful because it can't be reused without knowing which objects were involved in the calculation.
And without storing the result this method will not be bound to a state, i.e. it has to be static. And since interfaces can have static methods, instead of creating a utility class for that purpose it could be placed in the Surface interface. Like that.
public interface Surface {
public double area();
public static <T extends Surface> double calcArea(T[] t) { // generic method that receives Square and Circle arrays
double arrayArea = 0;
for (T a : t) {
arrayArea += a.area();
}
return arrayArea;
}
}
Note that static behavior declared in interfaces in contrast to classes could be invoked only by using the name of an interface:
System.out.println("Circle's sum area = " + Surface.calcArea(circ));
Also note that it makes sense for both classes to have a field area inside the classes Circle and Square only if other fields will be declared as final, i.e. they must be initialed only one during the object construction and setters become unnecessary.
In this case (assuming that radius has been declared as final and is being validated when assigned so that reduce > 0) method area() will look like this:
#Override
public double area() {
if (area > 0) { // `0` is a default value for instance variables
return area; // reusing already calculated value
}
return area = radius * radius * Math.PI;
}
And there mustn't be two methods area() and getArea() leave either one or another.
I have an interface with a superclass, a subclass, and a driver class. The interface must be implemented in the subclass, however, I am confused on how to do it. Do I implement the interface in the superclass and then extends the subclass?
The superclass is called store.
The subclass is called retail, it should receive the superclass's constructor, the number of items sold, unit price, and sale price should be array arguments. This class implements two methods that are defined at interface.
The interface should have two methods. One is the profit and the other is salary The profit method is to calculate the store profit in a week, and salary method is to calculate the store manager’s salary in a week.
/*
The interface should have two methods.
One is the “Profit” and the other is “Salary”.
The profit method is to calculate the store profit in a week, and salary method
is to calculate the store manager’s salary in a week.
*/
public interface Interface {
public void profit();
public void salary();
}
/*
The store class is a super class that receives store location,
manager name, hours worked, and hour rate.
This class should have the constructor that receives all of these.
It also should have get and set methods for each of fields.
This class also has “toString()” to
display restaurant location and manager’s name.
*/
public class Store {
private String location;
private String manager;
private int hours;
private int rate;
public Store(String l, String m, int hrs, int r) {
location = l;
manager = m;
hours = hrs;
rate = r;
}
public void setLocation(String l) {
location = l;
}
public String getLocation() {
return location;
}
public void setName(String m) {
manager = m;
}
public String getName() {
return manager;
}
public void setHours(int hrs) {
hours = hrs;
}
public int getHours() {
return hours;
}
public void setRate(int r) {
rate = r;
}
public int getRate() {
return rate;
}
public String toString() {
String result = "Store Location: " + location + "\n";
result += "Manager name:" + manager + "\n";
return result;
}
}
public class Retail extends Store {
private int items;
private double unit;
private double sale;
public Retail(String l, String m, int hrs, int r,int i, double u, double s){
super(l,m, hrs, r);
items = i;
unit = u;
sale = s;
}
public void profit() {
double[][] money = {{1.99, 2.99, 3.99, 4.99},
{5.99, 6.99, 7.99, 8.99},
{150, 48, 350,20}};
for (int i = 0; i < money.length; i++) {
for (int j = 0; j < money[i].length; j++) {
sum += money[i][j];
}
}
double profit = items * ( s - u);
}
public void salary() {
double pay = hrs * r;
//double salary = pay - ( pay * 0.05);
}
public double getSalary() {
double baseSalary = super.getHours();
}
public String toString() {
result += super.getName(); // inherited from superclass
String result = "Total Benefit: " + profit + "\n";
result += "Salary: " + salary + "\n";
return result;
}
}
General rules:
If the interface contract is applicable in the full hierarchy then implement it in the superclass and all subclasses adhere to the interface contract automatically.
You may choose to implement the interface in the superclass but make the superclass abstract if it does not have enough details to implement the interface methods. This way you can enforce the subclasses to adhere to the interface contract.
If the interface contract is not at all relevant to the full hierarchy then implement only in the applicable subclasses.
Your case:
In your example, the question is whether interface methods profit() and salary() applicable to any kind of Store? If yes (I assume it is), then go ahead and implement in the superclass. However, you may not be able to compute profit() and salary() in the Store class with the data points available. So, you may choose to declare Store class as abstract. In case you can implement these methods make Store class concrete.
On the other hand, if the interface methods profit() and salary() may not be applicable to all kind of Stores then go ahead and implement the interface only in Retail class.
Though I think the first option is the good one however, the choice is yours based on the business scenario.
I am trying to create a n-body simulator in Java while also learning OOP.
I want to have a file that contains all physical constants and physics formulas and I want to use these in other classes when calculating forces etc
Should this file be a regular class with all variables static, an interface or an abstract class, or something else? I am quite confused with all the definitions.
In your case I would create a class named Physics or something of that nature. Inside this class you can then accomplish all of the things you want to do by creating static methods and static variables, as JayC667 has pointed out. It should look something like this:
public class Physics {
public static final int GRAVITY_ACCELERATION = 9.58;
public static double formula(double x, double y) { ... }
// etc.
}
Then, to utilize this class from a different one, you simply reference the variables and use the methods like so:
System.out.println("Acceleration of Gravity = " + Physics.GRAVITY_ACCELERATION);
double speed = Physics.formula(23.5, 840);
You use interfaces to force classes (implementing those interfaces) to have defined methods (defined in the interface) you can can ensure basic functionality, while all the classes can be totally different in all other regards.
In an interface, you only define the method signature (return value, name, parameter types). These are purely abstract.
Since Java 8, interfaces can also contain default methods, that may contain code, but can be overridden by the implementing classes.
Best example is the Comparable interface. You can use that for Numbers, Strings, and any other classes that should be comparable (usually to their own class instances aka objects).
Abstract classes are a mixture of regular classes and interfaces. They contain code and member variables, but can also contain abstract methods. When a class extends an abstract base class, they need to implement the abstract methods at some point.
The normal classes do not have any abstract methods.
This is a question Java-developers usually fight over. General rules of thumb are the following:
If you use a static field, always make it final and never try to mutate it.
If you need a mutable field, create a non-static field.
If possible, initialise the field in the constructor and mark it final.
Methods are static only if they access no non-static fields (ie. they do not have a context), there is no need to abstract over them
(for example in a test case) and they are completely functional (this should
be implied by the fact that no static field is mutable). A good example is Math.sqrt(), where the square root operation does not have a context, does not mutate the state of your application and you never want to abstract over it. In all other cases use a non-static method. Some people completely avoid static methods.
Interfaces are most useful when your classes interact with one another. You can specify certain common functionalities available in a group of classes in your application. Then if some of your code requires these functionalities, you can use them without knowing the actual implementation. Say, you handle shapes in a method and want to know the area of a shape. You may have many shapes and you can retrieve the area without knowing the exact type (circle, triangle etc.).
In general, try not to overuse inheritance. Follow the substitution principle: only use inheritance if the superclass could always be substituted by the subclass.
For example: in OOP a square with variable slides is not a rectangle with variable slides, because for rectangles you are allowed to call setSide(20, 30), while for squares you are not (the two sides must match). Note: if you use final fields which are initialized in the constructor, as suggested earlier, this problem is automatically solved and you are free to inherit square from rectangle.
In your case, I would create utility classes with static methods/fields for common functionalities that do not have a context, such as calculating a formula with given input parameters. The actual bodies could be objects with common interface or abstract parent class.
This is some simple example of how you could do it.
Please ignore the aerial resistance part, didn't really think about that, some movements may be funny :-)
import java.util.ArrayList;
/**
* Contains constants and convenience methods
* #author JayC667
*/
class Globals {
static public final float GRAVITY_ACC = -9.81f; // meters per second²
static public float getTotalSpeed(final float pSpeedX, final float pSpeedY) {
return (float) Math.sqrt(Math.pow(pSpeedX, 2) + Math.pow(pSpeedY, 2));
}
static public float getDistanceBetweenObjects(final PhysicalObjectInterface pObj1, final PhysicalObjectInterface pObj2) {
final float distX = pObj2.getPosX() - pObj1.getPosX();
final float distY = pObj2.getPosY() - pObj1.getPosY();
return getTotalSpeed(distX, distY); // coincidentally same as average speed :-)
}
static public String toString(final PhysicalObjectInterface pObject) {
return pObject.getClass().getSimpleName() + "\tX=" + pObject.getPosX() + "\tY=" + pObject.getPosY();
}
}
interface PhysicalObjectInterface {
default boolean collidesWith(final PhysicalObjectInterface pOther) {
final float distance = Globals.getDistanceBetweenObjects(this, pOther);
return distance < getRadius() + pOther.getRadius();
}
float getPosX();
float getPosY();
float getSpeedX();
float getSpeedY();
float getMass();
float getRadius();
float getAerialResistanceCofactor();
void calcNextCycle();
}
/**
* Does most of the simple work
* #author JayC667
*/
abstract class PhysicalObjectABC implements PhysicalObjectInterface {
private float mPosX;
private float mPosY;
private float mSpeedX;
private float mSpeedY;
public PhysicalObjectABC(final float pPosX, final float pPosY, final float pSpeedX, final float pSpeedY) {
mPosX = pPosX;
mPosY = pPosY;
mSpeedX = pSpeedX;
mSpeedY = pSpeedY;
}
#Override public float getPosX() {
return mPosX;
}
#Override public float getPosY() {
return mPosY;
}
#Override public float getSpeedX() {
return mSpeedX;
}
#Override public float getSpeedY() {
return mSpeedY;
}
#Override public abstract float getMass();
#Override public abstract float getAerialResistanceCofactor(); // could also derive this from radius
// getRadius is not repeated here, but still is abstract and has to be defined in the implementing subclass
#Override public void calcNextCycle() {
final float gravForceY = getMass() * Globals.GRAVITY_ACC; // F = m * a
final float aerialResistForceX = -Math.signum(mSpeedX) * (float) (Math.pow(mSpeedX, 2) * getAerialResistanceCofactor());
final float aerialResistForceY = -Math.signum(mSpeedY) * (float) (Math.pow(mSpeedY, 2) * getAerialResistanceCofactor());
final float totalForceX = aerialResistForceX;
final float totalForceY = gravForceY + aerialResistForceY;
final float accX = totalForceX / getMass(); // a= F / m;
final float accY = totalForceY / getMass(); // a= F / m;
mSpeedX += accX;
mSpeedY += accY;
mPosX += mSpeedX;
mPosY += mSpeedY;
}
#Override public String toString() {
return Globals.toString(this);
}
}
class Stone extends PhysicalObjectABC {
public Stone(final float pPosX, final float pPosY) {
super(pPosX, pPosY, 0, 0);
}
#Override public float getRadius() {
return 0.1f;
}
#Override public float getMass() {
return 1;
}
#Override public float getAerialResistanceCofactor() {
return 0.2f;
}
}
class Leaf extends PhysicalObjectABC {
public Leaf(final float pPosX, final float pPosY) {
super(pPosX, pPosY, 0, 0);
}
#Override public float getRadius() {
return 0.1f;
}
#Override public float getMass() {
return 0.003f;
}
#Override public float getAerialResistanceCofactor() {
return 0.95f;
}
}
class StaticObject implements PhysicalObjectInterface {
private final int mPosX;
private final int mPosY;
private final int mRadius;
public StaticObject(final int pPosX, final int pPosY, final int pRadius) {
mPosX = pPosX;
mPosY = pPosY;
mRadius = pRadius;
}
#Override public float getPosX() {
return mPosX;
}
#Override public float getPosY() {
return mPosY;
}
#Override public float getSpeedX() {
return 0;
}
#Override public float getSpeedY() {
return 0;
}
#Override public float getMass() {
return 0;
}
#Override public float getRadius() {
return mRadius;
}
#Override public float getAerialResistanceCofactor() {
return 0;
}
#Override public void calcNextCycle() { /* ignore, does not move */}
#Override public String toString() {
return Globals.toString(this);
}
}
public class PhysicsEngine {
static private ArrayList<PhysicalObjectInterface> sObjects = new ArrayList<>();
public static void main(final String[] args) {
sObjects.add(new Leaf(10, 100));
sObjects.add(new Stone(20, 100));
sObjects.add(new Leaf(30, 100));
sObjects.add(new Stone(40, 100));
sObjects.add(new StaticObject(30, 100, 1)); // lantern
sObjects.add(new StaticObject(40, 100, 5)); // tree
for (int cycle = 0; cycle < 1000; cycle++) {
simulateCycle(cycle);
printData(cycle);
checkCollisions(cycle);
try {
Thread.sleep(1000);
} catch (final InterruptedException e) { /* ignore */}
}
}
private static void simulateCycle(final int pCycle) {
System.out.println("Simulating cycle #" + pCycle);
for (final PhysicalObjectInterface o : sObjects) {
o.calcNextCycle();
}
}
private static void printData(final int pCycle) {
System.out.println("Printing cycle #" + pCycle);
for (final PhysicalObjectInterface o : sObjects) {
System.out.println("\t" + o);
}
}
private static void checkCollisions(final int pCycle) {
System.out.println("Checking for collisions in cycle #" + pCycle);
final ArrayList<PhysicalObjectInterface> destroyedItems = new ArrayList<>();
for (final PhysicalObjectInterface o1 : sObjects) {
for (final PhysicalObjectInterface o2 : sObjects) {
if (o1 == o2) continue; // ignore IDENTICAL, not equal, items
if (o1.collidesWith(o2)) {
System.out.println("CRASH!\n\tObject 1 (" + o1 + ") \ncollides with \n\tObject 2 (" + o2 + ")");
destroyedItems.add(o1);
destroyedItems.add(o2);
}
}
}
sObjects.removeAll(destroyedItems); // can't delete within loop, would invalidate iterators or migh also f*** up loop indices
}
}
So I need to implement a getCurrentVolumeInCCs method for the vessel class, however I am a little confused as to how to do it. Also I am getting the correct values for the volume in both the Glass and Cup classes but when I call any of the other methods in the Vessel class these values do not get carried over. I'm guessing its because they are stored in the subclass and cannot be used in the base class, am I right?
Vessel Class (abstract)
package containers;
public abstract class Vessel {
private double volume;
private double currentVolume;
public Vessel() {
volume = 0;
currentVolume = 0;
}
abstract double getVolumeInCC();
public double getCurrentContents() {
return currentVolume;
}
public double drink(double amountToDrink) {
double volumeLeft;
System.out.println("you drank " + amountToDrink + " CCs");
volumeLeft = volume - amountToDrink;
return volumeLeft;
}
public double fill(double amountPoured) {
double volumeAdded = amountPoured;
double volumeSpilled = 0;
System.out.println("you poured " + amountPoured + " CCs");
if(volumeAdded > volume) {
volumeSpilled = amountPoured - volume;
System.out.println("you spilled " + volumeSpilled);
}
return volumeAdded;
}
}
Glass Class
package containers;
public class Glass extends Vessel{
private double volume;
private double radiusBase;
private double height;
public Glass() {}
public Glass(double r, double h) {
this.radiusBase = r;
this.height = h;
}
#Override
double getVolumeInCC() {
volume = (Math.PI)*(Math.pow(radiusBase, 2))*height;
return volume;
}
}
Cup Class
package containers;
public class Cup extends Vessel {
private double volume;
private double radiusLip;
public Cup(double r) {
volume = 0;
this.radiusLip = r;
}
#Override
double getVolumeInCC() {
volume = (0.5)*(Math.PI)*(Math.pow(radiusLip, 3))*(4/3);
return volume;
}
}
You are shadowing volume from Vessel in your subclasses because it's a private field. I believe that you wanted to make volume and currentVolume protected in Vessel,
protected double volume;
protected double currentVolume;
Also, you should remove private double volume from the sub-classes (so you don't shadow the field they now inherit from Vessel).
Ok,so I am getting a lot of trouble, I am still learning Java and my book has set me a task that I find common over the net, the part that I am stuck on is...
I must create a bank account program, an account holder is given a savings account (which has an interest rate and no overdraft facility), and a checking account (which has an overfraft facility of £100 and no interest).
I am not implementing the overdraft yet and am only half way to getting the withdraw and deposit function ready but my question is with the interest, I have defined in my superclass the savings account balance and the checking account balance so when working out my interest in the savings account class I cannot reference savebalance as I have made it private. I am trying to use the set.name method but i am clearly doing it wrong....
A big smile and a thank you for any one who can help or give advice!
Superclass is as follows:
public class BankDetails
{
private String customer;
private String accountno;
private double savebalance;
private double checkbalance;
//Constructor Methods
public BankDetails(String customerIn, String accountnoIn, double savebalanceIn, double checkbalanceIn)
{
customer = customerIn;
accountno = accountnoIn;
savebalance = savebalanceIn;
checkbalance = checkbalanceIn;
}
// Get name
public String getcustomername()
{
return (customer);
}
// Get account number
public String getaccountnumber()
{
return (accountno);
}
public double getcheckbalanceamount()
{
return (checkbalance);
}
public double getsavebalanceamount()
{
return (savebalance);
}
public void savewithdraw(double savewithdrawAmountIn)
{
savebalance = savebalance - savewithdrawAmountIn;
}
public void checkwithdraw(double checkwithdrawAmountIn)
{
checkbalance = checkbalance - checkwithdrawAmountIn;
}
public void savedeposit(double savedepositAmountIn)
{
savebalance = savebalance - savedepositAmountIn;
}
public void checkdeposit(double checkdepositAmountIn)
{
checkbalance = checkbalance - checkdepositAmountIn;
}
} // End Class BankDetails
Sub Class is as follows:
import java.util.*;
public class Savings extends BankDetails
{
private String saveaccount;
private double interest;
public Savings(String customerIn, String accountnoIn, float interestIn,
String saveaccountIn, double savebalanceIn)
{
super (customerIn, accountnoIn, savebalanceIn, interestIn);
saveaccount = saveaccountIn;
interest = interestIn;
}
public String getsaveaccountno()
{
return (saveaccount);
}
public double getinterestamount()
{
return (interest);
}
public void interestamount(String[] args)
{
BankDetails.getsavebalanceamount(savebalance);
interest = (savebalance / 100) * 1.75;
}
}
Use the superclass's getSaveBalance() method to access the balance (which is suspiciously-named, since you have a savings account class, but keep the balance elsewhere).
(Currently it's getsavebalanceamount(), I assume a renaming to keep with Java conventions.)
I'd recommend using consistent CamelCase when naming your getters and setters, e.g., getInterestAmount(), getSaveAccountNo(), etc.
I recommend against commenting simple getters/setters, but if you do, use Javadoc conventions, e.g.:
/** Returns current savings account balance. */
public double getSaveBalance() { ... etc ... }
I also recommend avoid unnecessary parentheses, as currently in your getters, e.g.:
public double getSaveBalance() {
return saveBalance; // No parens required.
}
I suggest you do something like this,
interface Account{
int getAccountNumber();
float getBalance();
}
public class SavingAccount implements Account, Interest{
int accountNumber;
public int getAccountNumber(){
return accountNumber;
}
float balance;
public float getBalance(){
return balance;
}
float savingInterestRate;
public float getInterestRate(){
return savingInterestRate;
}
}
public class CheckingAccount implements Account, OverDraft{
int accountNumber;
public int getAccountNumber(){
return accountNumber;
}
float balance;
public float getBalance(){
return balance;
}
}
interface Interest{
float getInterestRate();
}
interface OverDraft{
....
}