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.
Related
The title says it all, I got a class in which the variables of the constructor must be private.
public class AdMedia {
private String name;
private int price;
public AdMedia(){}
public AdMedia(String name, int price) {
this.name = name;
this.price = price;
}
that comes with public getter setter of the variables of course.
Now the problem comes right after I try to make a child class named Magazine. The class should inherit the name and price but the price is constant for every object initiation. so they won't be on the constructor as the name.
public class Magazine extends AdMedia {
private int area;
private String position;
private String topics;
public Magazine() {}
public Magazine(String name, int size, String position, String topic){
super();
this.size = size;
this.position = position;
this.topic = topic;
}
that also comes with its own getter setter too.
I try to put the price inside the constructor but the constructor demand a passed parameter. Using super(name) also notifies that none of parent constructor have such shape.
This complicates me when I'm trying to get the name using parent class method getName() which might require some downcasting I guess?
I had try to search for the solution but most require me to change the variable's accessibility into protected . Would there be no other way to do it in private ?
EDIT :
I forgot to mention that the result by doing what I wrote above is the unability to access Magazine name, so when I try to downcast-get the name, what returned is a null.
You could write your child constructor either as
public Magazine(String name, int size, String position, String topic){
super();
setName(name);
setPrice(100); // 100 is your constant price
this.size = size;
this.position = position;
this.topic = topic;
}
or as
public Magazine(String name, int size, String position, String topic){
super(name, 100); // 100 is your constant price
this.size = size;
this.position = position;
this.topic = topic;
}
Both ways would however open the possibility to change the price later:
Magazine m = new Magazine("name", 50, "position", "topic");
m.setPrice(10);
If you need to prevent this, you should also override the setPrice() setter:
public class Magazine extends AdMedia {
...
#Override
public void setPrice(int price) {
// what to do here?
// * you could either silently ignore
// (which might surprise some users expecting to be able to change the price)
// * throw an UnsupportedOperationException
// (which might surprise other users which are not prepared to handle such an exception)
}
}
I have the following interface:
public interface IStaff {
public StaffPosition getPosition();
public String toString();
}
and the class:
public class Worker implements IStaff {
private String name = null;
private String surname = null;
private int age = 0;
//StaffPosition is an enumeration class
private StaffPosition position= null;
public Worker (String name, String surname, int age, StaffPosition position){
this.name = name;
this.surname= surname;
this.age= age;
this.position= position;
}
#Override
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append(this.name);
buffer.append(" ");
buffer.append(this.surname);
return buffer.toString();
}
#Override
public StaffPosition getPosition() {
return this.position;
}
public int getAge(){
return this.age;
}
In another class - Building, I have a HashMap<Office, IStaff> officeswhere Office is a normal class which only holds the number of the office and has a getter for that number.
And then in a yet another class Company I have an ArrayList<Building> buildings, which holds information about all the buildings of a company. In this class I need to get the age of a worker but how can I do that? So far I have a loop like this to get to the map:
for (Building building: buildings) {
for (Map.Entry<Office, IStaff> office: building.offices.entrySet()) {
//get the age of a worker
}
}
Is there a way to do that?
The only real answer is: when you need such an information in places where only your interface should show up, then that information needs to sit on the interface.
So your interface could have a method getAge(), or maybe getBirthday().
Side notes:
using I for "interface" in class names ... is bad practice, or at least: very much against java conventions.
you don't need to have a toString() in your interface. You get one from Object anyway.
(of course, there are dirty tricks, like doing an instanceof check somewhere, and then casting to the type of the concrete class. But as said: that is really bad practice)
Make IStaff an abstract class and then call the method.
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
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'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());
}
}