【问题标题】:What's the implication of protected keywords in class definition in Scala?Scala 类定义中受保护关键字的含义是什么?
【发布时间】:2015-07-13 06:12:48
【问题描述】:

我正在通过练习“不耐烦的 Scala”一书中的练习来学习 Scala。一项练习要求:

文件Stack.scala包含定义class Stack[+A] protected (protected val elems: List[A])

解释protected关键字的含义。

有人可以帮我理解这个吗? protected 显然对成员变量有意义,但它在类定义中有什么含义?

【问题讨论】:

    标签: scala class generics covariance protected


    【解决方案1】:

    在 Scala 中,编写

    class Stack[+A](elems: List[A]) 
    

    还实现了默认构造函数。如果您了解 Java,那么在 Java 中这将类似于

    class Stack<A> {
        private List<A> elems; 
        public Stack<A>(List<A> elems){this.elems = elems;}
    }
    

    现在,您的示例中有两个 protected 关键字:

    • protected val elems: List[A]
    • protected (/*...*/)

    第一个使变量elems 受保护,这意味着它只能被Stack[+A] 的子类访问(和隐藏)。

    第二个使构造函数受保护,这意味着一个新的Stack 实例只能由Stack[+A] 的子类创建。

    同样,等效的 Java 代码类似于

    class Stack<A> {
        protected List<A> elems; 
        protected Stack<A>(List<A> elems){this.elems = elems;}
    }
    

    【讨论】:

    • 谢谢! +A是什么意思?
    • 表示Stack在泛型参数A中是协变的,也就是说Stack[Dog]是一个Stack[Animal]。如果不加加号,那么赋值val x: Stack[Animal] = Stack[Dog](Dog("Pluto"))是非法的。
    • 是的,在 Java 中,List&lt;Dog&gt; 不是 List&lt;Animal&gt;。那么逆变是-A呢?如果是这样,我想可以写class Stack[+A](elems: List[-A])?
    • 是的,逆变用减号表示。但是,如果我没记错的话,方差指示符只在声明一个类(或特征)时出现,所以实际上不允许写class Stack[+A](elems: List[-A])。如果你想表达elems 可以是A 的任何超类型的List,那么你可能会写class Stack[+A, B &gt;: A](elems: List[B]),其中[B &gt;: A] 就像在Java 中说&lt;B super A&gt;(和[B &lt;: A]就像说&lt;B extends A&gt;)
    • 优秀。协变-逆变是一个非常重要的概念,但是对于我不熟悉的 Scala 语法糖,很容易忽略这一点。再次感谢。
    猜你喜欢
    • 1970-01-01
    • 2020-10-22
    • 2018-09-13
    • 1970-01-01
    • 2011-04-21
    • 2018-05-05
    • 1970-01-01
    相关资源
    最近更新 更多