大家好我想尝试使用我的Fish class
中的属性来实现一个名为Catchable
的接口,在我的Fisher class
中,这是可能的,还是有部分接口我不理解。因为我认为我们被允许使用已经由接口实现的类中的属性,而在另一个类中,但是我仍然会出错:
Error: cannot find symbol
symbol: variable weight
location: variable item of type Catchable
Error: cannot find symbol
symbol: variable size
location: variable item of type Catchable
Error: cannot find symbol
symbol: variable weight
location: variable item of type Catchable .
对此有任何帮助或建议表示赞赏!
如果需要,这是我的Catchable
界面:
public interface Catchable
{
public float getWeight();
public boolean isDesirableTo(Fisher f);
}
我的Fish class
实现了Catchable
接口
public abstract class Fish implements Catchable
{
// Any fish below this size must be thrown back into the lake
public static int THROW_BACK_SIZE = 18;
public static float WEIGHT_LIMIT = 10;
protected float weight;
protected int size;
public Fish(int aSize, float aWeight)
{
size = aSize;
weight = aWeight;
}
public boolean isDesirableTo(Fisher f)
{
if(canKeep() && f.numThingsCaught < f.LIMIT && this.weight + f.sumOfWeight < WEIGHT_LIMIT)
{
return true;
}
else
{
return false;
}
}
public abstract boolean canKeep();
public int getSize() { return size; }
public float getWeight() { return weight; }
public String toString ()
{
return ("A " + size + "cm " + weight + "kg " + this.getClass().getSimpleName());
}
}
最后是我的Fisher class
import java.util.*;
public class Fisher
{
private String name;
private Catchable [] thingCaught;
public int numThingsCaught;
private int keepSize;
public float sumOfWeight;
public static int LIMIT = 10;
public String getName()
{
return this.name;
}
public int getNumThingsCaught()
{
return this.numThingsCaught;
}
public int getKeepSize()
{
return this.keepSize;
}
public Fisher(String n, int k)
{
name = n;
keepSize = k;
}
public String toString()
{
return(this.name + " with " + this.numThingsCaught + " fish");
}
private ArrayList<Catchable> thingsCaught = new ArrayList<Catchable>();
public void keep(Catchable item)
{
if(this.numThingsCaught < LIMIT)
{
thingsCaught.add(item);
numThingsCaught++;
sumOfWeight += item.weight;
}
}
public boolean likes(Catchable item)
{
if(item.size >= this.keepSize)
{
return true;
}
else
{
return false;
}
}
public void listThingsCaught()
{
System.out.println(this.toString());
for(Catchable item : thingsCaught)
{
System.out.println(item.toString());
}
}
public void goFishingIn(Lake lake)
{
Catchable item = lake.catchSomething();
if(likes(item))
{
this.keep(item);
}
else
{
lake.add(item);
}
}
public void giveAwayFish(Fisher fisher, Lake lake)
{
for(Catchable item : thingsCaught)
{
if(fisher.likes(item))
{
fisher.keep(item);
}
else
{
lake.add(item);
}
sumOfWeight -= item.weight;
}
thingsCaught.clear();
this.numThingsCaught = 0;
}
}
答案 0 :(得分:2)
并非每个Catchable
都是Fish
,例如
public boolean likes(Catchable item)
{
if(item.size >= this.keepSize)
...
将失败,因为Catchable
没有size
成员(它也不能拥有成员变量,因为它是一个接口)。这里item
为Catchable
,不是fish
。
当您使用接口时,您应该只通过接口中定义的方法(或扩展的接口)与实例进行交互。
答案 1 :(得分:2)
在Java中,我们通常将它们称为“字段”而不是“属性”。
无论如何,有几个问题。首先,您在weight
中将protected
(例如)声明为Fish
。这是正确的做法,但这意味着weight
无法在Fish
之外访问。因此,您必须从Fish
以外的类中执行此操作:
void example (Fish fish) {
// System.out.println(fish.weight); // <- not allowed, weight is protected
System.out.println(fish.getWeight()); // <- ok, getWeight() is public
}
首先在getWeight()
接口中提供类似Catchable
的公共getter(以及接口不能具有非静态非最终成员字段的事实)。底层实现是隐藏的 - 实现Catchable
的对象可能根本没有weight
字段,并且可能基于一些完全不同的规则计算返回值。但这没关系,因为您通过getWeight()
访问它。
其次,即使Catchable
Fish.weight
,上述内容对于一般public
也没有意义; Catchable
没有名为weight
的字段。 Fish
。因此,如果您通过Catchable
类型的引用访问它,则无论如何都没有weight
。
提供Catchable.getWeight()
。所有Catchable
类型都存在该方法。因此,您必须使用它来访问weight
。所以在Fisher
你可以这样做:
void example (Catchable catchable) {
// System.out.println(catchable.weight); // <- not allowed, Catchable has no weight
System.out.println(catchable.getWeight()); // <- ok, getWeight() is public and is in Catchable
}
我强烈建议您完成官方Interfaces and Inheritance教程。它可能会让您熟悉您所询问的一些概念。
<强>加了:强>
您似乎拥有C#或其他具有类似“属性”概念的语言背景 - 您提供了一个getter / setter,但在语法上您仍然可以通过属性名称直接引用它(例如fish.weight = 3
自动调用fish.setWeight(3)
。
Java中不存在此构造。您可以将getters / setter编写为成员方法,然后调用它们,这就是你得到的全部内容。在直接现场访问时不会自动调用getter / setter。你可以这样:
class Example {
public int field;
public void setSomething (int x) { ... }
public int getSomething () { ... }
}
这就是你得到的。你可以这样做:
Example x = ...;
x.field = ...;
... = x.field;
x.setSomething(...);
... = x.getSomething();
但你不能自动做这样的事情:
x.setField(...);
... = x.getField();
x.something = ...;
... = x.something;
因此,如果你有这样的语言背景,那可能是你混乱的根源。你需要调整。在Java中你必须明确;这种语言因其模糊性和冗余度低而值得注意。
答案 2 :(得分:2)
问题如下:
keep()
:
sumOfWeight += item.weight;
likes()
:
if(item.size >= this.keepSize)
giveAwayFish()
:
sumOfWeight -= item.weight;
在每种情况下,item
的类型为Catchable
,Catchable
没有size
或weight
个字段。您需要做的是致电item.getWeight()
而不是item.weight
并向getSize()
添加Catchable
方法,并致电item.getSize()
而不是item.size
:
Catchable
:
public interface Catchable
{
public float getWeight();
public int getSize();
public boolean isDesirableTo(Fisher f);
}
keep()
:
sumOfWeight += item.getWeight();
likes()
:
if(item.getSize() >= this.keepSize)
giveAwayFish()
:
sumOfWeight -= item.getWeight();
您不必修改Fish
,因为它已经实现了getSize()
。
你应该真正使用像Eclipse这样的IDE,因为它可以实时显示你的错误。
答案 3 :(得分:1)
我在你的代码中看到了这一点:
sumOfWeight += item.weight;
在这里放慢片刻 - 你没有使用类的具体实例;你指的是接口。你会发现接口没有weight
的字段,因此编译失败。
如果您想坚持使用界面,那么您需要更改一些内容。
在您的界面中添加方法getWeight()
。
public float getWeight();
从您的abstract
课程中删除Fish
声明(这只会让您感到伤心和迷惑)。
然后,当您想要执行该求和操作时,您可以:
sumOfWeight += item.getWeight();