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());
}
}
Related
I have two abstract classes i.e. Medicine and Prescription. All code can be found at https://codeshare.io/aVAdr3 These two classes have subclasses, the class hierarchy diagram is as follows:
and...
The medicine java file:
abstract class Medicine {
public String name;
public int price;
public Medicine (String name, int price) {
this.name = name;
this.price = price;
}
public int getPrice () {
return price;
}
public void setPrice (int newPrice){
price = newPrice;
}
}
class commonDrug extends Medicine {
public commonDrug (String name, int price) {
super(name, price);
}
}
The Prescription java file:
abstract class Prescription {
protected Medicine med;
public Prescription(Medicine med) {
this.med = med;
}
}
class bluePrescription extends Prescription {
public bluePrescription (Medicine med) {
super(med);
System.out.println(med.getPrice()+ "<-- Price for bluePrescription, it should be 30, but the calculations in pPrescriptions affect it.");
}
}
class whitePrescription extends Prescription {
public whitePrescription (Medicine med) {
super(med);
}
}
class pPrescription extends whitePrescription {
public pPrescription (Medicine med) {
super(med);
System.out.println(med.getPrice()+ "<-- Price before calculation for pPrescription");
//Calculations
int priceWithDiscount;
if (med.getPrice()<=20) {priceWithDiscount=0;}
else {priceWithDiscount= med.getPrice()-20;}
med.setPrice(priceWithDiscount);
System.out.println(med.getPrice()+ "<-- Price after calculation for pPrescription");
}
}
The test program is as follows:
class TestProgram {
public static void main (String[] args) {
//Medicine object
commonDrug drug1 = new commonDrug("Paracetamol", 30);
//Prescription objects:
pPrescription prescription1 = new pPrescription(drug1);
bluePrescription prescription2 = new bluePrescription(drug1);
}
}
And when you run the test program you get this in the terminal:
30<-- Price before calculation for pPrescription
10<-- Price after calculation for pPrescription
10<-- Price for bluePrescription, it should be 30, but the calculations in pPrescriptions affect it.
I've been trying to solve this for hours, I can't figure out how I can perform calculations in the pPrescription constructor without affecting instances of bluePrescription. Why is this happening? pPrescription is a subclass of whitePrescriptions, not bluePrescriptions. Anyhow, to instances of a class are completely separate, getPrice and setPrice are not static, so why is using them affecting all the instances of Medicine?
why is using them affecting all the instances of Medicine?
There is only once instance of Medicine in your code.
You pass the same object, i.e. drug1 to both pPrescription and bluePrescription class constructors.
As there's only one object (drug1) that is passed to both classes, if any class modifies it, changes will be reflected everywhere you refer to that object.
One way to fix the problem is to not save the discounted price and just calculate it whenever you need it using a method in the pPrescription class.
class pPrescription extends whitePrescription {
...
public int getDiscountedPrice() {
return med.getPrice() <= 20 ? 0 : med.getPrice() - 20;
}
}
Side note: Class names should begin with a capital letter.
I'm doing an assignment for school and im implementing a super but its not working yet i feel its done right. anyone have any idea why my super gives me a syntax error. It tells me "The Constructor Employee(String, String, String) is undefined yet it is though.
Here's my employee class that my other classes extend off of which have this super error.
/**
* Abstract class Employee - write a description of the class here
*
* #author (your name here)
* #version (version number or date here)
*/
public abstract class Employee
{
private String firstName;
private String lastName;
private String socialSecurityNumber;
public Employee(String first, String last, String ssn)
{
firstName=first;
lastName=last;
socialSecurityNumber=ssn;
}
public abstract double earnings();
public String toString()
{
return("\n"+firstName+" "+lastName+
"\nsocial security number: "+ socialSecurityNumber);
}
}
Here's one class with the super that gives me the issue.
public class SalariedEmployee extends Employee{
private double weeklySalary;
// four-argument constructor
public SalariedEmployee(String first, String last, String ssn, double salary) {
super(first, last, ssn); // pass to Employee constructor
setWeeklySalary(salary); // validate and store salary
} // end four-argument SalariedEmployee constructor
// set salary
public void setWeeklySalary(double salary) {
weeklySalary = salary < 0.0 ? 0.0 : salary;
} // end method setWeeklySalary
// return salary
public double getWeeklySalary() {
return weeklySalary;
} // end method getWeeklySalary
// calculate earnings; override abstract method earnings in Employee
public double earnings() {
return getWeeklySalary();
} // end method earnings
// return String representation of SalariedEmployee object
public String toString() {
return String.format("salaried employee: %s\n%s: $%,.2f",
super.toString(), "weekly salary", getWeeklySalary());
} // end method toString
} // end class SalariedEmployee
My other two classes like i said have the same issue so i don't think it would be necessary to post them but any help is greatly appreciated!
That may happens if you have another Employee class defined somewhere else in your project (could be in one of your .java file in the same package, some imports or in the classpath).
Your call to super(first, last, ssn) is all good. You may try to compile the two files in command line to confirm the above:
javac Employee.java SalariedEmployee.java
Apologies if the question has been asked before, though I did look around and couldn't find an applicable answer to my specific problem. Anyway, I'm trying to model a store that sells desserts which are all derived from a specific Dessert superclass.
When I try to run the program to test my classes, I get an error say "Cookie is not abstract and does not abstract method getPrice() in Dessert public class Cookie extends Dessert. I am getting the same error with another class called Fruit, but it is more or less the exact same as Cookie just with some different member variables and method names.
Here is the Dessert superclass:
public abstract class Dessert {
/** Name of the dessert item. */
protected final String name;
/**
* Constructs a new dessert item.
* #param name Name of the dessert.
*/
public Dessert(String name) {
this.name = name;
}
/**
* Get name of the dessert.
* #return dessert name
*/
public final String getName() {
return name;
}
/**
* Get the price of the dessert.
* #return Dessert price
*/
public abstract double getPrice();
}
And here is the Cookie subclass:
public class Cookie extends Dessert {
private int number;
private double price;
public Cookie (String name, int number, double price) {
super(name);
this.number = number;
this.price = price;
}
public int getItemCount() {
return number;
}
public double getPricePerDozen() {
return (price / 12) * number;
}
}
I can't seem to get the formatting right, but the lines immediately following the colons should be a part of the code block. As well as the curly braces following the block.
Thanks in advance for the help!
Since Cookie.java extends Dessert.java and the latter has an
abstract method getPrice()
Cookie.java must provide a definition for it. (Unless it itself is abstract.
One would do that if we had things such as OatmealCookie
ChocolateChipCookie that would be the definite class.)
I retyped the material quickly due to the problems git markdown and got
these to compile. I assume that the price for Cookie should simply be the
price per dozen and added the appropriate definition to it:
public abstract class Dessert {
protected final String name;
public Dessert (String name) {
this.name = name;
}
public final String getName() {
return name;
}
public abstract double getPrice ();
}
public class Cookie extends Dessert {
private int number;
private double price;
public Cookie (String name, int number, double price) {
super (name);
this.number = number;
this.price = price;
}
public int getItemCount() {
return number;
}
public double getPricePerDozen() {
return (price/12) * number;
}
public double getPrice() {
return getPricePerDozen();
}
}
Your Dessert class has an abstract method double getPrice(), and Cookie extends it, so Cookie needs to implement getPrice() or also be abstract in order to get rid of this error.
The code obviously doesn't compile in its current state, but think of it this way - If we were to instantiate a Cookie, its double getPrice() method is inherited from its super class Dessert, so the method would exist to be called, but it has no implementation in either Cookie or Dessert, so the result of calling it would be unspecified. Java sees this at compilation time, and so prevents you from trying to generate code that is ill-defined.
The Question is:
1) How can i get subclass parameter values to superclass?
2) i want to take the name(From subclass) for collection.sort , like this.model.compareTo(other.model). However, I don't know how to get the "Name" Value from subclass and do the collection.sort.
** Is it correct to write public int compareTo(Car other, Taxi other2)??? **
Here is the code:
public class Car implement comparable <Car>()
{
private string model;
private int price;
public car(String model , int price)
{
this.model=model;
this.price=price;
}
............some getmethod here..........
public int compareTo (Car other)
{
** Want to sort by name , like this.model.compareTo(other.model)**
}
}
Taxi.java:
public class taxi extends Car ()
{
private string name;
public taxi (String model , int price, String name)
{
super(model, price);
this.name = name;
}
......some getmethod here..........
}
you can use subclass values by creating object of sub class in superclass.
It is also known as delegation.
I have 2 class mentioned bellow .
first one :EmployeeDetails
package com.pacakge.emp;
public class EmployeeDetails {
private String name;
private double monthlySalary;
private int age;
//return name
public String getName()
{
return name;
}
//set the name
public void setName(String name)
{
name= this.name;
}
//get month sal
public double getMonthSal()
{
return monthlySalary;
}
//set month salary
public void setMonthSalry(double monthlySalary)
{
monthlySalary =this.monthlySalary;
}
Second one :EmpBusinessLogic
package com.pacakge.emp;
public class EmpBusinessLogic {
//calculate yearly salary of the employee
public double calculateYearlySalary(EmployeeDetails empdetails)
{
double yearlySalary;
yearlySalary =empdetails.getMonthSal()*12;
return yearlySalary;
}
This is my test class
package com.pacakge.emp;
import org.testng.Assert;
import org.testng.annotations.Test;
public class TestEmployeeDetails {
EmployeeDetails emp = new EmployeeDetails();
EmpBusinessLogic EmpBusinessLogic = new EmpBusinessLogic();
// Test to check yearly salary
#Test
public void testCalculateYearlySalary() {
emp.setName("saman");
emp.setAge(25);
emp.setMonthSalry(8000.0);
emp.getName();
System.out.println(emp.getName());
double salary = EmpBusinessLogic.calculateYearlySalary(emp);
Assert.assertEquals(salary, "8000");
}
}
Even if I have passed values from Test method values are not pass to the properties .
" System.out.println(emp.getName());" print null without any value.
any issue in the code ? couldn't find what is the issue ...
Your setters and getters are wrong...
Modify the name setter, for example, from:
name= this.name;
To:
this.name = name;
Explanation:
You're doing the assignment to the variable that is passed to the method instead of assigning it to the object variable. Same applies for monthlySalary and maybe other fields (you got a spelling mistake in the method name there as well: setMonthSalry()).