使用在另一个类中实现接口的类中的属性

时间:2014-02-23 01:20:03

标签: java variables methods interface

大家好我想尝试使用我的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;

  }

}

4 个答案:

答案 0 :(得分:2)

并非每个Catchable都是Fish,例如

public boolean likes(Catchable item)
{
    if(item.size >= this.keepSize)
...

将失败,因为Catchable没有size成员(它也不能拥有成员变量,因为它是一个接口)。这里itemCatchable,不是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的类型为CatchableCatchable没有sizeweight个字段。您需要做的是致电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();