1

问题链接

问题陈述:

您被要求在一家烘焙公司进行安全审计。他们的产品以 Bakery 类及其不同的子类(如 Cake 和 LemonTart)为代表。所有的糕点都装在漂亮的盒子里出售。在向客户发布之前,所有盒子都经过精心设计的 NaiveQualityControl 类检查。然而,最近发生了一些错误,无法食用的东西被装在盒子里,逃脱了质量检查。

对 NaiveQualityControl 的简短了解使您得出结论,为 NaiveQualityControl 提供装满纸的盒子非常容易,这将通过 QC。现在你的任务是证明这个错误。这是代码:

/* This class and its subclasses should pass quality check */
class Bakery {}

class Cake extends Bakery {}

/* This one should not */
class Paper {}

/* These boxes are used to pack stuff */
class Box<T> {
    void put(T item) { /* implementation omitted */ }
    T get() { /* implementation omitted */ }
}

/* This quality checker ensures that boxes for sale contain Bakery and anything else */
class NaiveQualityControl {
  
  public static boolean check(List<Box<? extends Bakery>> boxes) {
    /* Method signature guarantees that all illegal 
       calls will produce compile-time error... or not? */  
    return true;  
  }
  
}

您需要将实现添加到 Violator.defraud() 方法,该方法将执行以下操作:

  • 创建框列表<? 根据方法签名扩展 Bakery>
  • 将 Paper 对象放入列表中的至少一个 Box 中
  • 结果列表应通过 NaiveQualityControl 检查

我的解决方案:

import java.util.ArrayList;
class Violator {

    public static List<Box<? extends Bakery>> defraud() {
        Paper paper = new Paper();
        Box paperBox = new Box();
        paperBox.put(paper);
        List<Box<? extends Bakery>> boxes = new ArrayList<>();
        boxes.add(paperBox);
        return boxes;
    }
}

我的解决方案正在运行,但我使用命中和试用方法想出了它,所以我不知道为什么会这样。Paper 类如何即使没有扩展 Bakery 类仍然设法添加到框列表中?

还有一个疑问,为什么这个解决方案不起作用?

import java.util.ArrayList;
class Violator {

    public static List<Box<? extends Bakery>> defraud() {
        Paper paper = new Paper();
        Box<? extends Object> paperBox = new Box<>();// It should accept any type of box as any reference type is subclass of Object class...right?
        paperBox.put(paper);
        List<Box<? extends Bakery>> boxes = new ArrayList<>();
        boxes.add(paperBox);
        return boxes;
    }
}

错误:

Compilation error
Main.java:7: error: incompatible types: Paper cannot be converted to CAP#1
        paperBox.put(paper);
                     ^
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Object from capture of ? extends Object
Main.java:9: error: incompatible types: Box<CAP#1> cannot be converted to Box<? extends Bakery>
        boxes.add(paperBox);
                  ^
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Object from capture of ? extends Object
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
2 errors
4

0 回答 0