- public class User {
- private String name;
- private User(String name) { this.name=name; }
- private static theUser = new User("Nick");
- public static User instance() {
- return theUser;
- }
- }
public class User {
private String name;
private User(String name) { this.name=name; }
private static theUser = new User("Nick");
public static User instance() {
return theUser;
}
} |
- object User {
- var name:String = _
- def apply(name:String){this.name=name; this}
- override def toString = "name: " + name
- }
object User {
var name:String = _
def apply(name:String){this.name=name; this}
override def toString = "name: " + name
}
</pre></td></tr></tbody></table><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"> <span style="color: rgb(51, 51, 51); font-family: 宋体; font-size: 14px; background-color: rgb(249, 249, 249);">A singleton object that does not share the same name with a companion class is called a standalone object. You can use standalone objects for many purposes, including collecting related utility methods together, or defining an entry point to a Scala application.</span></p><h3 style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; background-color: rgb(249, 249, 249);"><a target=_blank name="t6"></a><a target=_blank name="_Toc282027560" class="ui-link " style="color: rgb(36, 137, 206);" target="_blank" rel="nofollow"></a><a target=_blank name="_Toc281660028" class="ui-link " style="color: rgb(36, 137, 206);" target="_blank" rel="nofollow"></a><span style="line-height: 24px; font-family: Consolas; font-size: 10.5pt;">4.1.5.<span style="line-height: normal; font-family: 'Times New Roman'; font-size: 7pt; font-weight: normal;"> </span></span><u><span style="line-height: 32px; font-family: 微软雅黑,sans-serif; font-size: 14pt;">静态方法</span></u></h3><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">Scala</span><span style="font-family: 宋体;">没有静态方法,类似静态方法的函数定义在</span><span style="font-family: Consolas;">object</span><span style="font-family: 宋体;">中:</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">object Stringx {</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"> def left(s0:String, s:String) = ...</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">}</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: 宋体;">直接调用</span><span style="font-family: Consolas;">Stringx.left(s0, s)</span><span style="font-family: 宋体;">,或者</span><span style="font-family: Consolas;"> Stringx left (s0, s)</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"> </span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: 宋体;">定义在</span><span style="font-family: Consolas;">object</span><span style="font-family: 宋体;">中的</span><span style="font-family: Consolas;">implicit</span><span style="font-family: 宋体;">方法也能被直接调用:</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: 宋体;">例如:</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">--------- <u>ImportSub.scala</u></span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="color: rgb(127, 0, 85); font-family: Consolas;">object</span><span style="font-family: Consolas;"> <span style="background-color: silver;">ImportSub</span> {</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"> </span><span style="color: rgb(127, 0, 85); font-family: Consolas;">def</span><span style="font-family: Consolas;"> fac(n: </span><span style="color: rgb(127, 0, 85); font-family: Consolas;">Int</span><span style="font-family: Consolas;">) = 1 to n reduceLeft (_ * _)</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"> </span><span style="color: rgb(127, 0, 85); font-family: Consolas;">implicit</span><span style="font-family: Consolas;"> </span><span style="color: rgb(127, 0, 85); font-family: Consolas;">def</span><span style="font-family: Consolas;"> foo(n: </span><span style="color: rgb(127, 0, 85); font-family: Consolas;">Int</span><span style="font-family: Consolas;">) = </span><span style="color: rgb(127, 0, 85); font-family: Consolas;">new</span><span style="font-family: Consolas;"> { </span><span style="color: rgb(127, 0, 85); font-family: Consolas;">def</span><span style="font-family: Consolas;"> ! = fac(n) }</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">}</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><a target=_blank name="_case_class" class="ui-link " style="color: rgb(36, 137, 206); font-weight: bold;" target="_blank" rel="nofollow"></a><span style="font-family: Consolas;">--------- <u>ImportMain.scala</u></span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="color: rgb(127, 0, 85); font-family: Consolas; background-color: yellow;">import</span><span style="font-family: Consolas; background-color: yellow;"> ImportSub._</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="color: rgb(127, 0, 85); font-family: Consolas;">object</span><span style="font-family: Consolas;"> ImportMain {</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"> </span><span style="color: rgb(127, 0, 85); font-family: Consolas;">def</span><span style="font-family: Consolas;"> main(args : </span><span style="color: rgb(127, 0, 85); font-family: Consolas;">Array</span><span style="font-family: Consolas;">[String]) : </span><span style="color: rgb(127, 0, 85); font-family: Consolas;">Unit</span><span style="font-family: Consolas;"> = {</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"> println(<span style="background-color: yellow;">5!</span>) </span><span style="color: rgb(63, 127, 95); font-family: Consolas;">// </span><span style="color: rgb(63, 127, 95); font-family: 宋体;">调用</span><span style="color: rgb(63, 127, 95); font-family: Consolas;">ImportSub</span><span style="color: rgb(63, 127, 95); font-family: 宋体;">中定义的</span><span style="color: rgb(63, 127, 95); font-family: Consolas;">implicit</span><span style="color: rgb(63, 127, 95); font-family: 宋体;">函数</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"> }</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">}</span></p><h3 style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; background-color: rgb(249, 249, 249);"><a target=_blank name="t7"></a><a target=_blank name="_Toc282027561" class="ui-link " style="color: rgb(36, 137, 206);" target="_blank" rel="nofollow"></a><a target=_blank name="_Toc281660029" class="ui-link " style="color: rgb(36, 137, 206);" target="_blank" rel="nofollow"></a><span style="line-height: 24px; font-family: Consolas; font-size: 10.5pt;">4.1.6.<span style="line-height: normal; font-family: 'Times New Roman'; font-size: 7pt; font-weight: normal;"> </span></span><u><span style="line-height: 32px; font-family: Consolas; font-size: 14pt;">case class(</span><span style="line-height: 32px; font-family: 微软雅黑,sans-serif; font-size: 14pt;">条件类</span><span style="line-height: 32px; font-family: Consolas; font-size: 14pt;">)</span></u></h3><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: 宋体;">例如:</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas; background-color: yellow;">case class</span><span style="font-family: Consolas;"> Person(name:String, age:Int) </span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: 宋体;">特殊之处:</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Wingdings;">l<span style="font-family: 'Times New Roman'; font-size: 7pt;"> </span></span><span style="font-family: 宋体;">新建类实例不用</span><span style="font-family: Consolas;">new Person(..)</span><span style="font-family: 宋体;">,直接用</span><span style="font-family: Consolas;">Person("qh",20)</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Wingdings;">l<span style="font-family: 'Times New Roman'; font-size: 7pt;"> </span></span><span style="font-family: 宋体;">自动定义好</span><span style="font-family: Consolas;">getXX</span><span style="font-family: 宋体;">方法,</span><span style="font-family: Consolas;">Person("qh",20).name // "qh"</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Wingdings;">l<span style="font-family: 'Times New Roman'; font-size: 7pt;"> </span></span><span style="font-family: 宋体;">提供默认的</span><span style="font-family: Consolas;">toString(), Person("qh",20) // "Person(qh,20)"</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Wingdings;">l<span style="font-family: 'Times New Roman'; font-size: 7pt;"> </span></span><span style="font-family: 宋体;">结合类继承可以通过模式匹配进行分解</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: 宋体;">例子</span><span style="font-family: Consolas;">1</span><span style="font-family: 宋体;">:</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">abstract class Person</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">case class Man(power:Int) extends Person</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">case class Woman(beauty:Int, from:String) extends Person</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"> </span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">val w1 = Woman(100,"china")</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">val w2 = w1.<span style="background-color: yellow;">copy</span>(from="usa") // Woman(100,"usa")</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"> </span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">def f(t:Person) = t match {</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas; background-color: yellow;">case Man</span><span style="font-family: Consolas;">(x) => "man's power:" + x</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas; background-color: yellow;">case Woman</span><span style="font-family: Consolas;">(x,y) => y + " beauty:" + x</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">}</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">f(Man(100)) // man's power:100</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">f(Woman(90, "china")) // china beauty:90</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"> </span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: 宋体;">注:基本类型直接可以用</span><span style="font-family: Consolas;"><a target=_blank class="ui-link" style="color: rgb(36, 137, 206); font-weight: bold;" href="http://qiujj.com/static/Scala-Handbook.htm#_match..case(switch)" target="_blank" rel="nofollow">math case</a></span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"> </span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: 宋体;">例子</span><span style="font-family: Consolas;">2</span><span style="font-family: 宋体;">:可变的类状态</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">case class C1(<span style="background-color: yellow;">var s</span>: String, <span style="background-color: yellow;">var ops</span>: Int) { </span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"> def >>= (f: (String=>String)) = {</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"> s = f(s) // s</span><span style="font-family: 宋体;">改变</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"> ops += 1 // ops</span><span style="font-family: 宋体;">改变</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"> this // </span><span style="font-family: 宋体;">返回自身,可以连续调用</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"> } </span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">} </span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">val C1(res, ops) = C1("ab", 0) >>= (_ * 3) >>= (_ drop 3)</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">// res="ab"->"ababab"->"bab", ops=0-> 0+1+1->2</span></p><p style="font-size: 14px; background-color: rgb(249, 249, 249);"><span style="color: rgb(204, 0, 0); font-family: Consolas;">细细体会构造对象,连续调用>>方法,然后match的这一系列过程。</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"> </span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: 宋体;">例子</span><span style="font-family: Consolas;">3</span><span style="font-family: 宋体;">:用</span><span style="font-family: Consolas;">case class</span><span style="font-family: 宋体;">代替</span><span style="font-family: Consolas;">tuple</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">val p = ("qh",20) // p._1 = "qh", p._2 = 20</span><span style="font-family: 宋体;">;好处是简洁,但无意义</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas; background-color: yellow;">case class person</span><span style="font-family: Consolas;">(name:String, age:Int)</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">val p = person("qh",20) // p.name = "qh", p.age = 20; </span><span style="font-family: 宋体;">好处是有名字,自说明,可读性强</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"> </span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: 宋体;">例子</span><span style="font-family: Consolas;">4</span><span style="font-family: 宋体;">:用</span><span style="font-family: Consolas;">case class</span><span style="font-family: 宋体;">来描述元数据</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">xml</span><span style="font-family: 宋体;">的版本:</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"><todo name = "housework"></span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"><item priority = "high">Clean the hose</item></span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"><item priority = "medium">Wash the dishes</item></span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"><item priority = "medium">Buy more soap</item></span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"></todo></span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">Scala</span><span style="font-family: 宋体;">的版本:</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"> case class item(priority:String, s:String)</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"> case class todo(name:String, items:List[item])</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"> todo (name="housework",</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">items=item("high","Clean the house")::</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">item("medium","Wash the dishes")::</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">item("medium","Buy more soap")::Nil)</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"> </span></p><h3 style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; background-color: rgb(249, 249, 249);"><a target=_blank name="t8"></a><a target=_blank name="_Toc282027563" class="ui-link " style="color: rgb(36, 137, 206);" target="_blank" rel="nofollow"></a><a target=_blank name="_Toc281660030" class="ui-link " style="color: rgb(36, 137, 206);" target="_blank" rel="nofollow"></a><span style="line-height: 24px; font-family: Consolas; font-size: 10.5pt;">4.1.7.<span style="line-height: normal; font-family: 'Times New Roman'; font-size: 7pt; font-weight: normal;"> </span></span><u><span style="line-height: 32px; font-family: Consolas; font-size: 14pt;">case object(</span><span style="line-height: 32px; font-family: 微软雅黑,sans-serif; font-size: 14pt;">条件单例对象</span><span style="line-height: 32px; font-family: Consolas; font-size: 14pt;">)</span></u></h3><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: 宋体;">比如定义一个标识类(而不是字符串):</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">case object Start</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">case object Stop</span></p><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;"> </span></p><h3 style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; background-color: rgb(249, 249, 249);"><a target=_blank name="t9"></a><a target=_blank name="_Toc282027564" class="ui-link " style="color: rgb(36, 137, 206);" target="_blank" rel="nofollow"></a><a target=_blank name="_Toc281660031" class="ui-link " style="color: rgb(36, 137, 206);" target="_blank" rel="nofollow"></a><span style="line-height: 24px; font-family: Consolas; font-size: 10.5pt;">4.1.8.<span style="line-height: normal; font-family: 'Times New Roman'; font-size: 7pt; font-weight: normal;"> </span></span><u><span style="line-height: 32px; font-family: 微软雅黑,sans-serif; font-size: 14pt;">枚举</span></u></h3><p style="color: rgb(51, 51, 51); font-family: Helvetica,Arial,sans-serif; font-size: 14px; background-color: rgb(249, 249, 249);"><span style="font-family: Consolas;">Java</span><span style="font-family: 宋体;">中:</span></p><pre style="color: rgb(51, 51, 51); background-color: rgb(249, 249, 249);" code_snippet_id="248416" snippet_file_name="blog_20140321_2_1518544"><span style="font-family: Consolas; font-size: 10.5pt;"> enum</span><span style="font-family: Consolas; font-size: 10.5pt;"> fruits { apple, banana, cherry }</span> 在Scala中,则是: sealed abstract class Fruits // sealed类似于java的final case object Apple extends Fruits case object Banana extends Fruits case object Cherry extends Fruits 也可以是 case class 4.1.9. 属性和Bean 例子1(直接定义和使用属性): class c { var name = "anonymous" // var定义的是r/w的属性 val age = 20 // val定义的是只r属性 } val o = new c o.name = "qh" o.name // "qh" o.age = 10 // 错误 o.age // 20 o. 例子2(定义get/set方法): class c2 { @reflect.BeanProperty var name = "anonymous" } val o2 = new c2 o2.name = "qh" // 也可以直接存取 o2.name // "qh" o2.setName("james") // 增加了set/get方法 o2.getName() // "james" 4.1.10. 反射 Scala没有太特别的反射机制,使用java的即可,不过Scala在match..case中可以匹配类型: case o:FooClass1 => ... 相关还有isInstanceOf[T], asInstanceOf[T] 例1(利用java的reflect): "hello".getClass.getMethods.map(_.getName).toList.sortWith(_<_).mkString(", ") 例子2: classOf[String] // 相当于java中的String.class "aaa".isInstanceOf[String] // true "aaa".asInstanceOf[String] 疑问:为什么是中括号而不是小括号呢?泛型? 4.2. trait超级接口 注:trait [treit] n.特征,特点,特性 和Java的Interface类似,但可以定义实体方法,而非仅仅方法定义 trait可以看作有方法实现和字段的interface;代表一类事物的特性; 比如 Tom,可能是Engine 和Son两个trait的混合; Sunny可能Sales、Son和Father三个trait的混合; 当在运行时往Son里面增加方法或者字段的时候,Tom和Sunny都得到增加的特性。 4.2.1. trait使用 trait Runnable { def run(): Unit; } 只是用一个接口,就用extends: class c1 extends Runnable {...} 2个接口(或一个继承一个接口),用with而不是implements如下: class c1 extends c0 with Runnable { def run(): Unit = {...} } 一个类可以组合多个trait: class c1 extends t1 with t2 with t3 {...} 4.2.2. mixin class Human class Child trait Dad { private var children:List[Child] = Nil def add(child:Child) = child :: children } class Man1(name:String) extends Human with Dad // 静态mixin class Man2(name:String) extends Human // 先不具备Dad trait val m1 = new Man1("qh") m1.add(new Child) val m2 = new Man2("小孩") // m2.add(new Child) // 报错 val m2$ = new Man2("james") with Dad // 动态mixin m2$.add(new Child) 4.3. 协变和逆变(co-|contra-)variance (找到应用,然后理解。仅仅是为了看懂定义中的符号?) 4.3.1. 概念 使用“+”“-”差异标记 Function[A, B]和Function[-A, +B]的区别图示:
|  |  | | Function[A,B] | Function[-A,+B] |
| trait Queue[T] {} | 非变 | | trait Queue[+T] {} | 协变 如果S extends A (S为子类型,A为父类型), 则Queue[S]为子类型,Queue[A]为父类型 S <: A => Queue[S] <: Queue[A] | | trait Queue[-T] {} | 逆变 如果S extends A (S为子类型,A为父类型) 则Queue[S]为父类型,Queue[A]为子类型,和协变互逆 S <: A => Queue[S] >: Queue[A] | -A是A的子集,叫逆变 +B是B的超集,叫协变 4.3.2. 类型上下界
| | | | <% | foo[T <% Ordered[T]](...) 关系较弱:T能够隐式转换为Ordered[T] | | <: | foo[T <: Ordered[T]](...) 关系较强:T必须是Ordered[T]的子类型,即T的类型范围小于Ordered[T],Ordered[T]为上界 | | >: | foo[T >: A](...) 关系较强:T必须是A的父类型,即Tde类型范围大于A,A为下界 | 4.3.3. 协变、逆变结合上下界 例子1:
| trait c1[+T] { def m[K >: T](x:K) = x } | trait c1[-T] { def m[K <: T](x:K) = x } | | object c2 extends c1[Int] c2.m(3) // 3 c2.m(3.0) // 3.0 c2.m("abc") // "abc" | object c2 extends c1[Int] c2.m(3) // 3 c2.m(3.0) // 报错 c2.m("abc") // 报错 | | | | 例子2: // 非变 case class T1[T](e:T) val v1:T1[java.lang.Integer] = new T1(100) val v2:T1[java.lang.Integer] = v1 v2.e // 100 val v3:T1[java.lang.Number] = v1 // 报错 // 协变 case class T1[+T](e:T) val v1:T1[java.lang.Integer] = new T1(100) val v2:T1[java.lang.Integer] = v1 v2.e // 100 val v3:T1[java.lang.Number] = v1 // 合法 v3.e // 100 val v4:T1[java.lang.Integer] = v3 //非法 // 逆变 class T1[-T](e:T) val v1:T1[java.lang.Number] = new T1(100) val v2:T1[java.lang.Number] = v1 val v3:T1[java.lang.Integer] = v1 // 合法 val v4:T1[java.lang.Number] = v3 // 非法 |