【问题标题】:Call/Assign a variable of a Class that implements an Interface调用/分配实现接口的类的变量
【发布时间】:2017-12-24 16:45:08
【问题描述】:

我写了一个简单的接口继承示例来说明我想要做什么。

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();
     }
}

所以 Banana 和 Strawberry 正在实施 Fruit。在午餐类中,我试图调用水果名称及其函数 taste(); 虽然调用函数味道很好,但我不能调用名称(请参阅:评论中的错误)

想要的输出: 我要吃香蕉! 好吃的香蕉!

就像我说的,美味的香蕉有效,但名称无法解析。我试图声明 "public String name = "default"";在水果界面。然后你可以调用它,但它总是说“默认”而不是实际类中的名称。

有没有办法获得实现接口的泛型类型的成员? 附:我需要这样做,当然这段代码只是为了表示,但我有一个更大更复杂的代码,我在其中遇到了这个问题——如果没有必要,我不想重组它。

提前谢谢你!

【问题讨论】:

  • 我会在接口中添加一个getName() 方法,并在该接口的实现中实现标准的getter/setter 方法。 (当然还要将 name 设为私有。)

标签: java class variables inheritance interface


【解决方案1】:

您的问题是由尝试直接访问实例成员引起的 - fruit.name - 而不是通过方法 - fruit.getName()

如果你使用getter方法,正确的方法将被执行并返回所需的输出。

也就是说,在这个特定的示例中,在基类中具有单个 getName() 方法和在该基类中具有单个 _name 变量会更有意义,根据水果类的实际类型。

另一方面,看到您的Fruit 是一个接口而不是基类,您可以让每个实现该接口的类都有一个返回不同值的getName() 方法。

例如:

class Strawberry implements Fruit {
     public String name = "Strawberry"; 
     public void taste(){
         System.out.println("yummy strawberry!");
     }
}

会变成:

class Strawberry implements Fruit {
     public String getName () {
         return "Strawberry";
     }
     public void taste() {
         System.out.println("yummy strawberry!");
     }
}

您必须在界面中添加getName()

interface Fruit {
     public String getName();
     public void taste();    
}

最后,您的Lunch 类变为:

class Lunch<Fruittype implements Fruit> {
     public Fruittype fruit;

     public void tasteit() {
         System.out.println("I'm going to eat a "+ fruit.getName() + "!" );
         fruit.taste();
     }
}

【讨论】:

  • 谢谢!没想到
【解决方案2】:

Case,当类实现接口时,表示该类的对象可以做接口中描述的事情。

例如,每个平面形状都有面积。所以我们可以确定接口:

interface PlaneShape {
    int getArea();
}

正方形的面积是边的乘积。圆的面积是 半径的平方除以 pi 数除以 2。所以:

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;
    }   
}

接口用于抽象。 AreaCalculator 使用平面形状进行操作,因此它从任何特定类型的平面形状中抽象出来。 AreaCalculator 只知道任何形状都可以通过执行 getArea() 方法给他面积值。 AreaCalculator 对特殊形状字段一无所知,例如 edgeradius

class AreaCalculator<S implemets PlaneShape> {
    public S shape;

    public int calculateArea() {
        shape.getArea();
    }
}

通过这种方式,在您的示例中,Lunch&lt;Fruittype implements Fruit&gt; 类对水果内部名称一无所知,它不会“看到”这个字段,它只能调用方法 taste()。您需要在接口中添加方法getName(),并实现它。

关于界面中name="default"的主题。它在接口的上下文中声明,与实现没有任何关系。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-16
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    相关资源
    最近更新 更多