本文主要针对于 Scala 中的方法 进行一个总结:
下面为本文的主要话题及思路:
1.方法种类:
1.1.类方法
1.2.对象方法
2.方法访问权限限制:
2.1.非继承
2.2.继承体系下的访问权限
2.3 final 方法的限制
3.方法参数:
3.1.默认参数
3.2.指定参数赋值
4.方法返回值:
4.1.多返回值 Tuple
5.方法异常:
5.1.方法抛出异常 / 与Java 进行交互
1.方法种类:
Scala 中的方法 主要分为以下两种类型:
1.类方法 相当于 Java 中的实例方法,就是是通过类的实例对象进行调用的
2.对象方法 相当于 Java 中的对象方法,跟类绑定
方法的主要部分:
def speakCC: Unit = {
speakCC -> 方法名
Unit -> 方法的返回值,Unit 代表了 Void
下面分别给出这两种方法的示例 :
1.1.类方法
类方法:
package methodDefine
/**
* Created by szh on 2018/12/6.
*/
class ClassFunc {
def speakCC: Unit = {
println("CC")
}
}
object ClassDefine1 extends App {
val d = new ClassFunc
d.speakCC
}
1.2.对象方法
package methodDefine
/**
* Created by szh on 2018/12/6.
*/
object ObjectFunc {
def staticSpeak(a: String): Unit = {
println(a)
}
}
object ObjectFunc2 extends App {
ObjectFunc.staticSpeak("CC-CC")
}
2.方法访问权限限制:
Scala 方法有一些 访问权限限定词,这些限定词 可以 控制我们 从访问到类中的方法。
主要的限定词如下 :
protected , private, private[this], private[module], 默认(无) 等 。。
scala 的限定与Java 中有所不同,我们看下不同修饰符对 可见性的控制。
整理的表格如下:
限定符 | 描述 |
(无修饰符) | 公开方法 |
protected | 对当前类及其子类的实例可见 |
private | 对当前类的所有实例可见 |
private[module] | **.module 包下的而所有类可见 |
private[this] | 仅当前实例可见 |
注意上面的描述中的意义是对调用环境的描述
下面我么分别给出非继承与继承关系下的测试
2.1.非继承
所在包 :
package methodDefine
示例:
package methodDefine
/**
* Created by szh on 2018/12/6.
*/
class LimitFunc {
//无修饰限定符,相当于Java 中的 public 方法
def publicFunc : Unit = {
println("No decorate of func, Just like public function")
}
//protected 对当前类及其子类的实例可见,与Java相同
protected def protectedFunc : Unit = {
println("decorate a func with protected , this will be seen in it's own and child")
}
//private 较为严格的限定,对当前类的所有实例可见
private def privateFunc : Unit= {
println("decorate a func with private, this func will only seen in it's own instance")
}
//private[module]
// private[module] 限定了只能在 module 下访问该方法
private[methodDefine] def privateModule : Unit = {
println("decorate a func like private[methodDefine], this will only seen is assign package")
}
private[this] def privateThis : Unit = {
println("decorate a func like private[this], this will only seen in it's own")
}
}
所在包:
顶层包
调用示例 :
import methodDefine.LimitFunc
/**
* Created by szh on 2018/12/6.
*/
object CallLimitClass extends App{
val d = new LimitFunc
d.publicFunc
// d.protectedFunc
//
// d.privateFunc
//
// d.privateModule
//
// d.privateThis
}
2.2.继承体系下的访问权限
所在包:
package methodDefine
继承体系:
package methodDefine
/**
* Created by szh on 2018/12/6.
*/
class LimitFunc2 {
//无修饰限定符,相当于Java 中的 public 方法
def publicFunc: Unit = {
println("No decorate of func, Just like public function")
}
//protected 对当前类及其子类的实例可见,与Java相同
protected def protectedFunc: Unit = {
println("decorate a func with protected , this will be seen in it's own and child")
}
//private 较为严格的限定,对当前类的所有实例可见
private def privateFunc: Unit = {
println("decorate a func with private, this func will only seen in it's own instance")
}
//private[module]
// private[module] 限定了只能在 module 下访问该方法
private[methodDefine] def privateModule: Unit = {
println("decorate a func like private[methodDefine], this will only seen is assign package")
}
private[this] def privateThis: Unit = {
println("decorate a func like private[this], this will only seen in it's own")
}
}
class LimitExtendFunc2 extends LimitFunc {
def allCall: Unit = {
publicFunc
privateModule
protectedFunc
//privateFunc
//privateThis
}
}
调用类
所在包: 顶层包
示例:
import methodDefine.LimitExtendFunc2
/**
* Created by szh on 2018/12/6.
*/
object CallLimitClass2 extends App {
val d = new LimitExtendFunc2
d.publicFunc
d.allCall
// d.protectedFunc
//
// d.privateFunc
//
// d.privateModule
//
// d.privateThis
}
2.3 final 方法的限制
final 对方法的限制,请参考我的另一篇文章:
Scala_类-》类的继承
https://blog.csdn.net/u010003835/article/details/84853237
3.方法参数:
Scala 的方法,可以指定默认值,这个是Java 所不具备的,这个应该是参考了 C++的一些方案
3.1.默认参数
scala 支持给 方法的参数 默认值。下面给出示例:
注意一个重要事项,默认参数 应该从右边往左边设置,就是不能有间断的情况,这是一个原则:
def qq(userName: String, tel: Long, addr: String = "xxxx"): Unit =
package methodDefine
/**
* Created by szh on 2018/12/6.
*/
class FuncDefaultVal {
def qq(userName: String, tel: Long, addr: String = "xxxx"): Unit = {
println(s"$userName $tel $addr")
}
}
object FuncDefaultVal extends App {
val f = new FuncDefaultVal
f.qq("qq", 222)
}
3.2.指定参数赋值
有的时候,我们调用方法的时候,参数比较多。我们不清楚那个顺序,但是我们知道参数的名字,我们可以这样调用。
通过直接指定参数名的方式:
f.qq(tel = 222, userName = "ccc")
package methodDefine
/**
* Created by szh on 2018/12/6.
*/
class FuncDefaultVal {
def qq(userName: String, tel: Long, addr: String = "xxxx"): Unit = {
println(s"$userName $tel $addr")
}
}
object FuncDefaultVal extends App {
val f = new FuncDefaultVal
f.qq("qq", 222)
f.qq(tel = 222, userName = "ccc")
}
4.方法返回值:
对于一般方法的返回值,我们有时候可能有多返回值的需求,Scala 不同于 Go, 直接支持多返回值。
它可以借助于Tuple 辅助的完成多返回值。
4.1.多返回值 Tuple
下面给出一个返回Tuple 来达到多返回值的例子
package methodDefine
/**
* Created by szh on 2018/12/6.
*/
class FuncTupleReturn {
def getMultiReturn: Tuple3[Long, Long, Long] = {
(1, 2, 2)
}
}
object FuncTupleReturn extends App {
val d = new FuncTupleReturn
val reVal = d.getMultiReturn
println(s"${reVal._1} ${reVal._2} ${reVal._3}")
val x = reVal._1
println(x.getClass)
val y = reVal._2
println(y.getClass)
val z = reVal._3
println(z.getClass)
}
5.方法异常:
本篇不详细讲解Scala 的异常机制,与继承关系。Scala 的异常机制 与 Java 模型基本一致。
5.1.方法抛出异常 / 与Java 进行交互
我们在编写Scala 代码的时候,有时候Scala 代码可能会抛出异常,有的时候我们还需要与Java类进行交互,此时我们应该如何处理呢?
在Scala 自身调用中,我们其实并不用声明抛出了异常,
但是追求合理的设计,我们最好也要声明类抛出了何种异常。这个时候我们可以选用注解的方式,对方法可能抛出的异常进行声明。这样的好处是,即使在Java调用Scala 的方法代码中,我们也能知道该类可能抛出的异常,这样,可以在Java调用方法的时候就行合适的处理,防止Java 不知道抛出何种异常而意外终止。
当不是用
@throws(classOf[Exception]) 注解时:
Scala 代码:
package methodDefine
/**
* Created by szh on 2018/12/6.
*/
class ExceptionThrows {
//@throws(classOf[Exception])
def mayException = {
throw new Exception("This is an error")
}
}
object TestPP extends App{
val f = new ExceptionThrows
f.mayException
println("zz")
}
"C:\Program Files\Java\jdk1.8.0_45\bin\java" "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2017.1.5\lib\idea_rt.jar=55917:D:\Program Files\JetBrains\IntelliJ IDEA 2017.1.5\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_45\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_45\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_45\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_45\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_45\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_45\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_45\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_45\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_45\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_45\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_45\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_45\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_45\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_45\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_45\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_45\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_45\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_45\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_45\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_45\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_45\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_45\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_45\jre\lib\rt.jar;E:\180-scala-online-modules\module1\target\classes;C:\Users\szh\.m2\repository\org\scala-lang\scala-library\2.11.6\scala-library-2.11.6.jar" methodDefine.TestPP
Exception in thread "main" java.lang.Exception: This is an error
at methodDefine.ExceptionThrows.mayException(ExceptionThrows.scala:10)
at methodDefine.TestPP$.delayedEndpoint$methodDefine$TestPP$1(ExceptionThrows.scala:18)
at methodDefine.TestPP$delayedInit$body.apply(ExceptionThrows.scala:15)
at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
at scala.App$$anonfun$main$1.apply(App.scala:76)
at scala.App$$anonfun$main$1.apply(App.scala:76)
at scala.collection.immutable.List.foreach(List.scala:381)
at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
at scala.App$class.main(App.scala:76)
at methodDefine.TestPP$.main(ExceptionThrows.scala:15)
at methodDefine.TestPP.main(ExceptionThrows.scala)
Process finished with exit code 1
可以看到执行的时候,可以编译通过。
证明 @throws(classOf[Exception]) 注解 只是建议性 注解,但是为了我们的代码友好性,跟方便Java 调用,我们一般建议还是加上该注解。
加上注解后,Java 调用代码
import methodDefine.ExceptionThrows;
/**
* Created by szh on 2018/12/6.
*/
public class CallScalaException {
public static void main(String[] args) {
ExceptionThrows a = new ExceptionThrows();
a.mayException();
}
}
可以看到会被给予提示,所以我们对可能出现异常的Scala 类应该加上 @throws(classOf[Exception]) 注解