Eiffel:我可以使用`expanded SOME_DEFERRED_CLASS`吗?

时间:2016-11-19 03:43:49

标签: polymorphism abstract-class instantiation eiffel

import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.Random; public class Safelock { static class Friend { private final String name; private final Lock lock = new ReentrantLock(); public Friend(String name) { this.name = name; } public String getName() { return this.name; } public boolean impendingBow(Friend bower) { Boolean myLock = false; Boolean yourLock = false; try { myLock = lock.tryLock(); yourLock = bower.lock.tryLock(); } finally { if (! (myLock && yourLock)) { if (myLock) { lock.unlock(); } if (yourLock) { bower.lock.unlock(); } } } return myLock && yourLock; } public void bow(Friend bower) { if (impendingBow(bower)) { try { System.out.format("%s: %s has" + " bowed to me!%n", this.name, bower.getName()); bower.bowBack(this); } finally { lock.unlock(); bower.lock.unlock(); } } else { System.out.format("%s: %s started" + " to bow to me, but saw that" + " I was already bowing to" + " him.%n", this.name, bower.getName()); } } public void bowBack(Friend bower) { System.out.format("%s: %s has" + " bowed back to me!%n", this.name, bower.getName()); } } static class BowLoop implements Runnable { private Friend bower; private Friend bowee; public BowLoop(Friend bower, Friend bowee) { this.bower = bower; this.bowee = bowee; } public void run() { Random random = new Random(); for (;;) { try { Thread.sleep(random.nextInt(10)); } catch (InterruptedException e) {} bowee.bow(bower); } } } public static void main(String[] args) { final Friend alphonse = new Friend("Alphonse"); final Friend gaston = new Friend("Gaston"); new Thread(new BowLoop(alphonse, gaston)).start(); new Thread(new BowLoop(gaston, alphonse)).start(); } }是不可能的,因为:

  1. x: expanded SOME_DEFERRED_CLASS类不能用于对象实例化。
  2. deferred类型不允许polymorphism
  3. 我错过了什么,或者我是对的吗?

2 个答案:

答案 0 :(得分:2)

x: expanded A_CLASS是一种过时的语法。它不再受支持。

但是expanded可以在类定义中使用。在这种情况下,正如您所引用的那样,不可能同时使用延迟类和扩展类。

作为一个简单的规则,可以定义一个只包含下一个列表中的一个的类:expandeddeferredseparatefrozen

如果你要"扩展"一个已经存在的实现,你只需要创建这个类的扩展继承人。看看Eiffel的内核库,你可以找到这样的例子(例如INTEGER_32 - 扩展类 - 继承INTEGER_32_REF

答案 1 :(得分:1)

你是对的。推理可以改写如下:

  1. 没有类型将直接符合扩展类型。
  2. 如果类型被展开,它只符合自身。 (从1.有更多的一致性规则,但对于扩展类型,它们最多只能涉及通用参数。)
  3. 只有正确设置了特定类型的实体才能使用。
  4. 只有在使用相同类型的对象实例化扩展类型的实体时,才能使用该实体。 (从2和3开始。)
  5. 延迟类型不能用于实例化。
  6. 不能使用延迟扩展类型的实体。 (从4和5开始。)
  7. 因此,即使从技术上讲,也许可以允许声明延期扩展类型的实体,但它们无法使用。

    正如在另一个答案中正确指出的那样,在现代的Eiffel中,只有一个类标记可用于表示其状态,因此,在语法上不可能声明延迟的扩展类或类型。然而,即使它被允许,也没用。

    修改

    有两种一致性:直接一般。直接一致性反映了父子关系:没有传递性或反身性规则,类型NONE的特殊规则等等。它基本上表明,如果类C继承自类{{1}在某些条件下,类型P符合类型C。这些条件排除了扩展P时的情况。

    一般一致性使用直接一致性作为基本案例之一与其他一些案例一起使用,例如:反身性规则“一种类型符合自身”。因此,规则“没有类型直接符合扩展类型”只是意味着继承链接对扩展类型无关紧要。但由于反身性规则,扩展类型仍然符合自身。

    所有这些细节背后的注释“ From 1 ”。更多信息可以在Standard ECMA-367(第8.14节)中找到。