Scala 类定义中受保护关键字的含义是啥?

Posted

技术标签:

【中文标题】Scala 类定义中受保护关键字的含义是啥?【英文标题】: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 显然对成员变量有意义,但它在类定义中有什么含义?

【问题讨论】:

【参考方案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 语法糖,很容易忽略这一点。再次感谢。

以上是关于Scala 类定义中受保护关键字的含义是啥?的主要内容,如果未能解决你的问题,请参考以下文章

JAVA中处理异常的5个常用关键字是啥?代表啥含义?

Java的概念和定义是啥?

Scala之Object (apply) dycopy

scala 使用case 关键字定义类不需要创建对象直接调用

scala——关键字trait的使用

如何影响派生类中受保护的基变量