Java Generic Class Can't Find Method - java

For my CS assignment I need to write a generic Bag object that implements the container interface. The Bag should only be able to hold items that implement the Thing interface. My problem, is when I try to compile, I get the this...
Bag.java:23: error: cannot find symbol
if (thing.getMass() + weight >= maxWeight) {
symbol: method getMass()
location: variable thing of type Thing
where thing is a type-variable:
Thing extends Object declared in class Bag
the getMass() method is clearly defined in the Thing interface, but I can not get the Bag object to find it. Here are my class files...
public interface Thing {
public double getMass();
}
public class Bag<Thing> implements Container<Thing> {
private ArrayList<Thing> things = new ArrayList<Thing>();
private double maxWeight = 0.0;
private double weight = 0.0;
public void create(double maxCapacity) {
maxWeight = maxCapacity;
}
public void insert(Thing thing) throws OutOfSpaceException {
if (thing.getMass() + weight >= maxWeight) {
things.add(thing);
weight += thing.getMass();
} else {
throw new OutOfSpaceException();
}
}
}
public interface Container<E> {
public void create(double maxCapacity);
public void insert(E thing) throws OutOfSpaceException;
public E remove() throws EmptyContainerException;
public double getMass();
public double getRemainingCapacity();
public String toString();
}
I posted all of my code that i feel is relevant to save space. If the problem is difficult to locate, i can post every line. Just let me know.

There's an extra <Thing> that's confusing the compiler. Change
public class Bag<Thing> implements Container<Thing> {
to
public class Bag implements Container<Thing> {
Right now you're creating a new type variable named Thing that hides the existing Thing interface. What you're writing now is equivalent to
public class Bag<E> implements Container<E>
...just with a variable named Thing instead of E.

Related

Does a class which implements an interface's method (without explicitly implementing that interface) extend that specific interface?

I am implementing a class to store objects that can be assigned a double value. For this reason, I have created a HasDoubleValue interface, that contains a single method:
public interface HasDoubleValue{
public double doubleValue();
}
My main class is defined as such:
Data <O extends HasDoubleValue> {...}
Now, when I try to initialize this class to store Integers, I get a "type argument Integer is not within bounds of type-variable O" error, although Integer implements the doubleValue() method by default.
I suppose that this happens because Integer does not explicitly implement my HasDoubleValue interface, although it has the method I am looking for. Is this right? What would a natural workaround be?
Yes, it is right. Java doesn't use duck-typing as JavaScript or TypeScript.
A solution is to create an adapter class that wraps a Integer, delegates to it, and actually implement the interface.
Or, since inthis case your interface is a functional interface, to use a lambda or a method reference to create an instance of HasDoubleValue from an Integer.
public interface HasDoubleValue{
double doubleValue();
}
final class IntegerHasDoubleValueAdapter implements HasDoubleValue {
private final Integer i;
public IntegerHasDoubleValueAdapter(Integer i) {
this.i = i;
}
#Override
public double doubleValue() {
return i.doubleValue();
}
}
class Data<O extends HasDoubleValue> {
void put(O o) {}
public static void main(String[] args) {
Integer i = 42;
Data<IntegerHasDoubleValueAdapter> d1 = new Data<>();
d1.put(new IntegerHasDoubleValueAdapter(i));
Data<HasDoubleValue> d2 = new Data<>();
d2.put(() -> i.doubleValue());
Data<HasDoubleValue> d3 = new Data<>();
d3.put(i::doubleValue);
}
}

Call/Assign a variable of a Class that implements an Interface

I wrote an easy interface-inheritance example to illustrate what I'm trying to do.
interface Fruit{
public void taste();
}
class Banana implements Fruit {
public String name = "Banana";
public void taste(){
System.out.println("yummy banana!");
}
class Strawberry implements Fruit {
public String name = "Strawberry";
public void taste(){
System.out.println("yummy strawberry!");
}
}
class Lunch<Fruittype implements Fruit> {
public Fruittype fruit;
public void tasteit() {
System.out.println("I'm going to eat a"+ fruit.name + "!" );
// error: name cannot be resolved or is not a field
fruit.taste();
}
}
class exec {
public static void main(String[] args) {
Lunch<Banana> bananalunch = new Lunch<>;
bananalunch.fruit = new Banana();
bananalunch.tasteit();
}
}
So Banana and Strawberry are implementing Fruit. In the class Lunch I'm trying to call the fruit name and its function taste();
While calling the Function taste works just fine, i can't call the name (see: error in the comment)
Wanted Output:
I'm going to eat a Banana!
yummy banana!
Like I said, yummy banana works but the name can't be resolved. I tried to declare "public String name = "default""; in the Fruit interface. Then you can call it, but it will always say "default" and not the name in the actual class.
Is there a way to get a member of a generic Type that implements an interface?
P.S. I need to do it like this, of course this code was only for representation but I have a much larger more complicated code in which i encountered this problem- And I don't want to restructure it if not necessary.
Thank you in advance!
Your problem is caused by trying to access an instance member directly - fruit.name - instead of via a method - fruit.getName().
If you use a getter method, the correct method will be executed and return the required output.
That said, in this particular example it would make more sense to have a single getName() method in a base class, and a single _name variable in that base class, which is initialized to a different value based on the actual type of fruit class.
On the other hand, seeing that your Fruit is an interface rather than a base class, you can have each of the classes which implement that interface have a getName() method returning a different value.
For example:
class Strawberry implements Fruit {
public String name = "Strawberry";
public void taste(){
System.out.println("yummy strawberry!");
}
}
would become:
class Strawberry implements Fruit {
public String getName () {
return "Strawberry";
}
public void taste() {
System.out.println("yummy strawberry!");
}
}
You would have to add getName() to the interface:
interface Fruit {
public String getName();
public void taste();
}
Finally, your Lunch class becomes:
class Lunch<Fruittype implements Fruit> {
public Fruittype fruit;
public void tasteit() {
System.out.println("I'm going to eat a "+ fruit.getName() + "!" );
fruit.taste();
}
}
Case, when class implements interface, means that object of this class can do something that described in interface.
For example, every plane shape has area. So we can determine interface:
interface PlaneShape {
int getArea();
}
Area of square is product of edges. And area of circle is product of
squared radius by pi number divided by 2. So:
class Square implements PlaneShape {
public int edge = 5;
public int getArea() {
return edge*edge;
}
}
class Circle implements PlaneShape {
public int radius = 5;
public int pi = 3.14;
public int getArea() {
return radius*radius*pi/2;
}
}
Interfaces use for abstraction. AreaCalculator operates with plane shapes, so it abstracts from any specific kind of plane shapes. AreaCalculator just knows that any shape can give him area value by executing method getArea(). AreaCalculator don't know anything about special shape fields, like edge or radius.
class AreaCalculator<S implemets PlaneShape> {
public S shape;
public int calculateArea() {
shape.getArea();
}
}
By this way, in your example,Lunch<Fruittype implements Fruit> class don't know anything about fruits inner names, it doesn't "see" this fields, it only can invocate method taste(). You need to add method getName() to interface, and implement it.
On the subject of name="default" in interface. It declared in context of interface and hasn't any relation to implementations.

abstract classes, inheritance, best way to do programm with figures

import java.lang.Math;
public class FiguraProba
{
public abstract class Figura {
public abstract double pole();
public abstract double obwod();
}
public abstract class Czworokat extends Figura {
public double obwod(double bok1, double bok2, double bok3, double bok4)
{
return (bok1+bok2+bok3+bok4);
}
public abstract double pole();
}
public class Kwadrat extends Czworokat {
double bok1;
public Kwadrat(double bokPodany)
{
bok1=bokPodany;
}
public double pole(double bok1) {
return bok1*bok1;
}
}
public class Prostokat extends Czworokat {
double bok1, bok2;
public Prostokat(double bokPodany1, double bokPodany2)
{
bok1=bokPodany1;
bok2=bokPodany2;
}
public double pole(double bok1, double bok2) {
return bok1*bok2;
}
}
public static void main(String args[] )
{
//System.out.println(Math.sin(90*(Math.PI/180)));
}
}
I apologize for my English and using English variable names. My goal is: I have object f.e squareExample with side 5. I want to call function to compute area from class square and call function perimeter from class quadrange to compute perimeter. Is it possible?
Compilator says: "FiguraProba.Prostokat is not abstract and does not ovveride abstract method pole() in FiguraProba.Czworokat." I understand the error but I dont know how to work out the error to achieve the goal.
Sorry for using code variables and classes in a foreign language. Here is the explanation what all the words mean:
figura - figure
kwadrat - square
czworokat - quadrangle
prostokat - rectangle
pole - area
obwod - perimeter
bok - side
The solution would be the following:
import java.lang.Math;
public class FiguraProba
{
public abstract class Figura {
public abstract double pole();
public abstract double obwod();
}
public abstract class Czworokat extends Figura {
public double obwod(double bok1, double bok2, double bok3, double bok4)
{
return (bok1+bok2+bok3+bok4);
}
public abstract double pole();
}
public class Kwadrat extends Czworokat {
double bok1;
public Kwadrat(double bokPodany)
{
bok1=bokPodany;
}
// Method without any arguments like the Figura class
// When you extend an abstract class, you have to
// implement the exact method with the exact number of arguments
// Of course you are obligated only if you can create an instance
// of that object. The perfect example when you are not obligated to
// implement a method is class Czworokat. Czworokat is not
// obligated, because you can not create an instance out of it.
public double pole() {
return bok1*bok1;
}
}
public class Prostokat extends Czworokat {
double bok1, bok2;
public Prostokat(double bokPodany1, double bokPodany2)
{
bok1=bokPodany1;
bok2=bokPodany2;
}
// Same logic applies here.
// When you extend an abstract class, you have to
// implement the exact method with the exact number of arguments
// Of course you are obligated only if you can create an instance
// of that object. The perfect example when you are not obligated to
// implement a method is class Czworokat. Czworokat is not
// obligated, because you can not create an instance out of it.
public double pole() {
return bok1*bok2;
}
}
public static void main(String args[] )
{
//System.out.println(Math.sin(90*(Math.PI/180)));
}
}
This would be what you want in case you would only use the classes properties and return the value on behalf of that. If you do want the pole methods with one and two arguments (like you have it in the code), then you would still need to remove the abstract pole method OR you would need to implement that exact method with ZERO arguments.
You can not breach the contract by NOT implementing pole with no arguments. If you need a deeper understanding about abstract classes, then I would suggest you to take a look at the official Java documentation.
If you are overriding a method from abstract class you have to write it exacly what it looks like in interface. So your method should have the same name and the same arguments.
In other worlds, you have a method with signature double pole(double bok1), but you still have to override method dobule pole();

Java interface classes?

So, I am trying to learn how the interface classes in Java Work, and i'm really confused about it.
I wan't to make it like a method in a normal class file like this:
public class APIClass {
private int davs;
public int setInt(int dav) {
this.davs = dav;
return davs;
}
public int getInt() {
return davs;
}
}
Two methods. One that set's the int "davs", and one getting the int "davs".
What i wan't to do in the interface is something like that. I have seen in others interface files, that they have something like this:
public interface MyInterface {
public MyInterface setInt(int davs);
public MyInterface getInt();
}
EDIT:
My question is that i can't see what i can use the interface for? All i have seen use it, declare the same method in a new class file, and then they really don't need the interface file. So what is it for?
Interfaces in Java are meant as an abstraction. You're expected to use it strictly for deriving other classes. You don't declare any methods in it all.
So if you have an interface like this:
public interface MyInterface {
int setInt(int davs); // this should probably return void
int getInt();
}
And you implement it in a class like this:
public class APIClass implements MyInterface {
private int da;
public int setInt(int davs) {
// return da; <- this doesn't make a whole lot of sense
da = davs; // I assume you meant this
return da; // usually you don't return anything from a setter
}
public int getInt() {
return dada;
}
}
And another class like this:
public class SecondAPIClass implements MyInterface {
private int dada = 0;
public int setInt(int davs) { // note that you have to keep the same method signiture in all derived classes
dada = davs + 5;
return dada;
}
public int getInt() {
return da;
}
}
You can use the interface to group them both. This is an important part of object oriented design. It's usefulness is probably too long to explain in a simple StackOverflow question, but here's a simple example of its usefullness:
import java.util.ArrayList;
public static void main(String[] args)
{
APIClass first = new APIClass();
SecondAPIClass second = new SecondAPIClass();
first.setInt(20);
second.setInt(20);
ArrayList<MyInterface> list = new ArrayList<MyInterface>();
list.add(first);
list.add(second);
for(MyInterface item : list) {
System.out.println(item.getInt());
}
}
The output should be this:
20
25
This example might be more helpful:
Consider you have several vehicles. All vehicles can drive, but driving a boat is different from driving a car, or a helicopter. This is where interfaces are useful. You can declare what a Vehicle should do, without dictating how it should do it.
public interface Vehicle {
void drive();
}
So when you derive it in a class Car, you can state how you want this vehicle to drive.
public class Car implements Vehicle {
void drive() {
// drive like a car
}
}
Now boats are vehicles, and they can drive too, but driving a boat is much different than driving a car.
public class Boat implements Vehicle {
public void drive() {
// drive like a boat
}
}
In summary, interfaces are useful when you have an abstract concept in mind, where you know what derived objects should do but can't dictate how they do it.

"has private access" error with generics

I had a problem I could actually solve myself, but I still don't understand why my original code doesn't work, or if there is a more elegant solution than the one I found. I'm presenting a simplified version of my code here.
Consider the following abstract superclass X:
public abstract class X{
private int i;
public void m1(X x){
x.i = 1;
m2(x);
}
public abstract void m2(X x);
}
When m1 is called, we manipulate a private field of X of the instance passed, and then we call m2 with that instance.
I have several subclasses of X, they are all alike in the sense that they also declare private members which they manipulate. In order to achieve that, they always need to make a cast at the beginning of m2. Here is one of them:
public class Y extends X{
private int j;
public void m2(X x){
Y y = (Y) x;
y.j = 0;
}
}
But - I can guarantee that every call of m1 of an instance of a subclass of X will always have a parameter that is of the same type, e.g. when I have an instance of Y, the parameter of the method m1 will always be another instance of Y.
Because of that guarantee, I wanted to make the cast unnecessary, by introducing generics. This is how I want my subclasses to look like:
public class Y extends X<Y>{
private int j;
public void m2(Y y){
y.j = 0;
}
}
How does the superclass X have to look like now? My first try was that:
public abstract class X<T extends X<T>>{
private int i;
public void m1(T x){
x.i = 1;
m2(x);
}
public abstract void m2(T x);
}
But - that doesn't work, when I compile this, I get the following error:
X.java:6: error: i has private access in X
That's usually what you get you try to access the private members of another class. Obviously, Java doesn't recognise that T is always an instance of X as well, although I used "T extends X" in the declaration.
I fixed X like this:
public abstract class X<T extends X<T>>{
private int i;
public void m1(T x){
X<?> y = x;
y.i = 1;
m2(x);
}
public abstract void m2(T x);
}
At least I'm not using casts any more - but why is this extra assignment necessary? And why didn't the original code work? Also, I found it strange I had to use X<?> and could not use X<T>.
I believe we can reduce your question down to: Why does the following example fail to compile?
public class Foo {
private final String bar = "bar";
public <T extends Foo> void printFoo(T baz) {
System.out.println(baz.bar); //bar is not visible
}
}
It's a great question, and it sure took me by surprise. But we can actually remove Generics from the equation by noting that this doesn't work either:
public class Foo {
private final String bar = "bar";
public void printFoo(SubFoo baz) {
System.out.println(baz.bar); //bar is not visible
}
}
class SubFoo extends Foo {
}
In other words, the issue is that you're dealing with a subclass of Foo, not Foo itself. In the case of T, we don't know which subclass, but we know it is a subclass, or Foo.
As you've already figured out, the solution (surprisingly, at least to me) is to upcast:
System.out.println(((Foo)baz).bar);
Or for the Generic case:
public <T extends Foo> void printFoo(T baz) {
System.out.println(((Foo)baz).bar);
}
Is the cast so bad? Not really. It's certainly as good or better than avoiding the cast with an intermediate variable. As with any upcast, I would assume it would be removed by the compiler. It exists only as a hint to the compiler. We certainly don't have to worry about the safety of the cast, because the erasure of T is already Foo.
I can only assume this restriction is required so as to be clear about the access...since SubFoo could redeclare bar itself, it could become ambiguous which bar is being referred to, and so the cast is necessary. This is demonstrated in this complicated example:
public class Foo {
private final String bar = "hello";
static class SubFoo extends Foo {
private final String bar = "world";
}
public <T extends SubFoo> void printFoo(T baz) {
// System.out.println(baz.bar); // doesn't compile
System.out.println(((Foo)baz).bar); //hello
System.out.println(((SubFoo)baz).bar); //world
}
public static void main(String[] args) {
new Foo().printFoo(new SubFoo()); //prints "hello\nworld"
}
}
In this regard, it serves more as a qualifier than as a cast.

Categories

Resources