Scala学习笔记(二)
Scala面向对象:
类:
声明类(一个源文件中可以包含很多public的类)
getter和setter
构造函数(主构造器和附属构造器)
继承(extends)
重写父类方法(override def)
重写字段(override val,override var)
1.声明类
/** * * 在scala 中,类默认是public,而且一个源文件可以包含多个public,源文件名可以和文件中定义的类名不一致 */ class Person { val name:String = "jack" //普通类不允许声明一个变量不给任何值的指定 var age:Int = _ //var 可以不指定值,给个占位符 //定义一个私有成员 // private[this] val gender:String = "male" //private 在哪个包能访问,其他的包不能访问 private[this] var gender:String = "male" //可以通过暴露一个getter来访问类中的私有成员 def getGender:String = { this.gender } def setGender(gender:String){ this.gender = gender } //定义成员方法 def sayHello(msg:String){ println(msg) } } object Person{ def main(args: Array[String]): Unit = { //默认无参构造函数,可以不用带括号 val p = new Person println(p.name) p.age = 18 println(p.age) //跟java中一样,不能对私有成员进行访问 p.gender println(p.getGender) p.setGender("nonFemale") println("new Gender: "+p.getGender) p.sayHello("today is very fine,i like it") } }
2.构造函数:
//class 有一个默认的无参构造器 //带参的主构造器,就是在类名后指定参数,主构造器的参数会被编译成类的成员变量(前提:参数必须有val或者var) class Book(val name :String ,var price:Float) { //类定义中的语句其实就是在主构造器方法体中 println("这是在Book类的主构造器") private[this] var author :String = _ //附属构造器,名称一定是this,参数不能带var或者val def this (name:String,price:Float,author:String){ //一定要在第一行调用主构造器 this(name,price); this.author = author println("这是在Book类附属构造器中") } def sayHello{ println("hello world") } sayHello } object Book{ def main(args:Array[String]):Unit = { val b = new Book("hadoop权威",100,"张三") println(b.name) println(b.price) b.price=80F; println("new price " + b.price); } }
3.继承:
class TestExtends { } //先执行父类的构造函数,在执行子类的构造函数 //子类继承父类的成员变量,所以在主类构造器中的相应参数可以不带val或者var,子类特有的成会员变量应该带val或者var class Teacher(val name:String,val age :Int ){ val major :String = "math"; println("在Teacher的主构造器中......") } class CollegeTeacher(name:String,age:Int,school:String) extends Teacher(name,age){ //重写父类中的成员变量, 必须加override修饰符 override val major:String = "HighLevelMath" println("在CollegeTeacher的主构造器中......") //在父类中已经实现的方法,子类重写时一定要加override override def toString: String="override toString......" } object Runner{ def main(args: Array[String]): Unit = { val ct = new CollegeTeacher("tom",33,"TsingHua") println(ct.toString) println(ct.major) } }
抽象类(abstract class):
类的一个或者多个方法没有完整的定义
声明抽象方法不需要加abstract关键字,只需要不写方法体
子类重写父类的抽象方法时不需要加override
父类可以声明抽象字段(没有初始值的字段)
子类重写父类的抽象字段时不需要加override,否则需要override
class TestAbstractClass { } //定义抽象类,要加abstract关键字 abstract class AbstractParent { //可以定义有初始化的成员 val name: String = "jack" //也可以定义没有初始化的成员,即抽象成员 val age: Int //可以定义有具体是实现的方法 def add(x: Int, y: Int) = x + y //也可以定义抽象方法 def concat(a: String, b: String): String println("in the abstract parent......") } class son extends AbstractParent { //抽象的成员或者方法 在子类中实现时,不需要加override //抽象父类中的抽象成员在子类中必须实现 //给个占位符或者具体值 val age:Int = 18 //抽象父类中的抽象方法必须在子类中实现 def concat(a:String,b:String):String = a+b //重写抽象父类中的成员或者方法 ,必须加override override val name :String = "tom" override def add(x:Int,y:Int)= x+ y + 10 println("in the son") } object son{ def main(args: Array[String]): Unit = { val s = new son println("add function " + s.add(4,5)) } }
特质(trait)—-对比java8中的接口
字段和方法的集合
混入类中
通过with关键字,一个类可以扩展多个特质
class TestTrait { } class AbstractParent01 {} //定义一个trait特质 trait Logger { //trait 中也可以定义抽象方法 def append(msg: String): Unit //trait 中可以定义具体实现的方法 def log(info: String) { println("INFO: logging in traint Logger......" + info) } } trait ConsoleLogger extends Logger { //子trait中可以实现父trait中的抽象方法,也可以不去实现,保持抽象 def append(msg: String): Unit = { println("append in the ConsoleLogger......") } //子trait可以重写父trait中有具体实现的方法,一定要加override关键字 override def log(info: String) { println("INFO: logging in traint Logger......" + info) } } //通常用with来“继承”trait, 但是如果子类没有其他的父类,则用extends 关键字来“继承”trait class ClassA extends AbstractParent01 with Logger { //必须实现trait中的抽象方法 def append(msg: String) {} val name: String = "jack" } class ClassB extends ConsoleLogger { } //定义一个普通类,在定义时没有指定继承任何trait,但是在创建时,可以临时混入trait class ClassC{ } object Runner01 { def main(args: Array[String]): Unit = { val ca = new ClassA println(ca.name) ca.log("Successfully with a trait") println("-------------------") val b = new ClassB b.log("User zhangsan loged in") println("------------------") //可以在创建对象时混入trait,扩展类的功能 val c = new ClassC with ConsoleLogger c.log("Successful with a trait when instaniating a class") }
apply方法
单例对象
class TestApply { } class AAA{ def test(): Unit ={ println("worked in class AAA") } def apply(): Unit ={ println("apply in class AAA") } } object AAA{ //注意:此处的new AAA()是调用class AAA的构造器,返回的是AAA的是实例对象 //相当于一个创建类实例的普通工厂方法 //def apply()= new AAA() //改造一下,就成了一个创建单例对象的工厂方法 var aaa:AAA = _ def apply() = if(aaa == null ){aaa= new AAA();aaa}else aaa } object AAA0{ def apply(): Unit ={ println("apply in object AAAo") } } object Runner{ def main(args: Array[String]): Unit = { //apply方法可以被显示调用 AAA0.apply() //更多地是通过对象名加圆括号来调用 AAA0() //对象是一样的道理 val a = new AAA a.apply() a() //通过调用类AAA的伴随object AAA的apply方法来初始化一个AAA类的实例对象 //apply方法通常就是通过这样一种模式来为一些类进行实例对象的创建 val aaa = AAA() aaa.test val aaa1 = AAA() println(aaa.toString) println(aaa1.toString) } }
模式匹配
标准用法(match)
使用守卫
匹配类型
object TestMatchCaseDemo { def main(args: Array[String]): Unit = { val a = 1 a match { case 1 => println("it is 1") case 2 => println("it is 2") case _ => println("other thing ") } a match{ case x if x==1 => println("it is 1 again") case x if x==2 => println("it is 2 again") case _ => println("other thing again ") } def test(a:Int) =a match{ case 1 => println("it is 1 in function ") case 2 => println("it is 2 in function") case _ => println("other thing in function") } test(3) def t(obj:Any) = obj match{ case x:String => {println("it is a String ");x} case x:Int => println("it is a Int") case _ => println("it is some other ") } t(Array("tom")) println(t("jack")) } }
case class(多用在模式匹配中)
构造器中的每一个类型默认都为val
不用new就可以直接产生对象(为什么?apply方法)
class TestCaseClass { } //case class 用关键字 case 来定义 //主构造器中的参数不应加val或者var,也会被自动地编辑成成员变量 //在case class中,主构造器中的参数默认是val ,且不建议用var case class User(name:String,psw:String){ } object TestCaseClass { def main(args: Array[String]): Unit = { //获得一个case class 的实例对象,不用显示new,而是直接"类名(参数)"就可以(为什么?apply()方法) val u = User("tom","a good boy") u match { //匹配类型的标准写法 //case i:User => println("it is a User......") //匹配类型的另一种写法,可以根据传入构造函数的具体字段进行精确匹配 case User("tom","a good boy") => println("it is a User of tom and 123") case User("jack","a good boy") => println("it is a User of jack and 123") case x:TestCaseClass => println("it is a TestCaseClass......") case _ => println("it is some other thing......") } //在scala中很多场景下可能会看到两个case class:Some(代表有值) 和 None(代表无值),它们都是option的子类 val m = Map(1->2,3->4); var x :Int = 0 m.get(x) match { case Some(_) => println("key exists......") case None =>println("key not exists.....") case _ => println("other......") } } }
文件访问
按行读取
按字符读取
从网络读取
import scala.io.{Codec, Source} class TestFileRead { } object TestFileRead{ def main(args: Array[String]): Unit = { //读取本地文件 val file = Source.fromFile("F:\\上网账号.txt")(Codec("GBK")) //按字符访问 // for(c <- file){ // println(c) // } //按行访问 // for( file <- file.getLines()){ // println(file) // } //读取网页 val webHtml = Source.fromURL("http://www.www.163.com/","GBK"); for (line <- webHtml.getLines()){ println(line) } } }
微信公众号

作者:chaplinthink
===> [欢迎赞赏作者, 您的赞赏,是我前进的动力🙂]
出处:https://www.cnblogs.com/bigdata1024/p/8387415.html
本文以学习、研究和分享为主,如需转载,请联系本人,标明作者和出处,非商业用途!
出处:https://www.cnblogs.com/bigdata1024/p/8387415.html
本文以学习、研究和分享为主,如需转载,请联系本人,标明作者和出处,非商业用途!
posted on 2017-06-08 22:04 chaplinthink 阅读(185) 评论(0) 编辑 收藏 举报
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· Windows桌面应用自动更新解决方案SharpUpdater5发布
· 我的家庭实验室服务器集群硬件清单
· C# 13 中的新增功能实操
· Supergateway:MCP服务器的远程调试与集成工具
· Vue3封装支持Base64导出的电子签名组件