Scala是完全面向对象编程的,没有static、接口等概念。
结构化编程是遵循按部就班的解决问题原则,俗称面向过程,先做什么后做什么,而面向对象编程是把一个问题分成多个小问题,把一个系统分成多个不同的组成部分,每个 部分有他自己的功能,最后整合在一起。
面向对象编程中,一切事物皆对象,小到每个元素,大到飞机轮船,完事万物皆对象,不一定是物体,还可以是事件,计划等。
具有相同属性的对象统称为一类,类是对象的抽象存在,对象是类的具体存在,每一个对象都是他所在类的一个实例。
Java是一种面向对象的语言,但是它不是完全面向对象的,Java中的基本数据类型,null,static,接口。这些属性的与面向对象思想产生矛盾。同时Scala源自Java,是完全面向对象的语言,在编程过程中可以实现和Java的无缝对接。
关于Java的更多面向对象编程原理,请点击下方链接:
面向对象基础
面向对象高级
下面是我们对比着Java和Scala进行的语法说明。
Java:在一个类文件中可以出现多个类,但是每个类文件中只能有一个公共的类(即public 修饰)。而且类名必须与文件名相同。
Scala:一个源文件中也可以出现多个类,但是在Scala中,类不是用public修饰,都是自动公共可见的。
Java:强类型语言,在创建对象的时候必须声明对象类型。
Scala:推断机制可以根据对象推断出对象类型,因此不必声明。(但是不满足多态的用法。)
//Person person = new Person();
//val person:Person = new Person()
val person = new ScalaPerson //自动推断类型,不必声明
Java:属性初始化的过程中,如果没有赋值,则Java会自动为其提供一个默认值。Java中的Setter 和 getter是用来访问属性的,起到了封装的作用。
下面我们来看Scala
在这里我们介绍一个小工具——jd-gui。
这是一款可以读取class字节码文件进行反编译后分析得到源Java代码的工具。
下面是我们自己写的类的创建,属性及其getter setter方法的创建。
package com.nefu.scala.chaptor01
/** *******************
*
* @auther Dr.Li
* @create 2019-11-08 16:20
* ********************/
class ScalaPerson {
private var name:String = _ //没有默认值,必须手动添加值(可以自动推断出值)
def getName: String = {
return name
}
def setName(name: String): Unit = {
this.name = name
}
}
将其进行编译在jd-gui小工具中反编译查看:
可以看出我们的getter和setter方法都不必写。
下面我们把自己写的getter setter注掉。并且直接操作person的属性。
class ScalaPerson {
var name:String = _ //没有默认值,必须手动添加值(可以自动推断出值)
// def getName: String = {
// return name
// }
//
// def setName(name: String): Unit = {
// this.name = name
// }
}
val person = new ScalaPerson //自动推断类型,不必声明
person.name = "SGG"
println(person.name)
运行后的结果:
"C:\Program Files\Java\jdk1.8.0_151\bin\java.exe" "-javaagent:D:\AboutMyWork\MyDevelopmentTool\IntelliJ_Idea\IntelliJ IDEA Community Edition 2019.2.3\lib\idea_rt.jar=59509:D:\AboutMyWork\MyDevelopmentTool\IntelliJ_Idea\IntelliJ IDEA Community Edition 2019.2.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_151\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_151\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_151\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_151\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_151\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_151\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_151\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_151\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_151\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_151\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_151\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_151\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_151\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_151\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_151\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_151\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_151\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_151\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_151\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_151\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_151\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_151\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_151\jre\lib\rt.jar;D:\AboutMyWork\IDEA-WorkSpace\ScalaDemo\ScalaExamples\target\classes;D:\AboutMyWork\MyDevelopmentTool\Maven\Repository\org\scala-lang\scala-library\2.11.8\scala-library-2.11.8.jar" com.nefu.scala.chaptor01.ScalaTest
SGG
Process finished with exit code 0
在进行编译查看源码
综上所述:
1.Scala声明一个属性,一定要为其初始化,Scala可以根据初始化的值为它推测数据类型,因此数据类型不必声明,如果初始化值为null,则应用“ _”来表示。
2.Scala对属性的访问具有访问一致性,因此不推荐开发者写setter getter方法,Scala自己为其声明了 getter setter方法。
3.如果属性的访问权限是private,则setter getter也是private
4.如果属性的没有声明访问修饰符,则说明访问权限是对外开放的。
Java的方法调用是
对象.方法名()
Scala中的方法一般称之为函数请参照下面这篇文章的有关内容:
Java中的静态方法不是对象调用的,而是类调用的,因此不是面对象的。
Scala语言是完全面向对象的,不存在static的静态的属性方法。Scala所拥有的是伴生对象,用object修饰,其中内容都是static修饰。是伴生类的所有属性和方法的集合,可以使用伴生类名.属性(函数)来进行调用,伴生类应该和伴生对象应该在同一个文件之中。
class ScalaPerson {
var name:String = _ //没有默认值,必须手动添加值(可以自动推断出值)
// def getName: String = {
// return name
// }
//
// def setName(name: String): Unit = {
// this.name = name
// }
}
object ScalaPerson{
val age = 100
def testMethod():Unit = {
println("ScalaPerson.testMethod()")
}
def main(args: Array[String]): Unit = {
val person = new ScalaPerson
person.name = "Alex"
ScalaPerson.testMethod()
}
}
Java的包名主要是来管理名字相同的一些类,只要在使用的时候加全路径就行,Java的包名和Java文件的存储位置息息相关。
Scala的包名与源码文件的存储位置无关,技术上来看,包名经过编译会行成符合Java语法的包结构。
都是通过关键字extends继承父类的属性和方法。
// class 子类名 extends 父类名 { 类体 }
Java只能是单继承,但是可以多实现,接口中的属性必须是常量,方法必须是抽象的。
Scala中用特质(征)来表示Java的中的接口的概念,用关键字trait声明。特征表示具有某种能力,一个类一旦继承了这个特征,就说明它具有这个能力。
继承的关键字是extends,多继承用with连接。
有两种写法:
/*
类名 extends 父类 with 特质1 with 特质2
类名 extends 特质1 with 特质2 with 特质3.
*/
两个特质:
trait Animal {
def move(): Unit ={
println("运动")
}
}
trait HighAnimal{
def think(): Unit ={
println("思考")
}
}
类继承并多继承
class ScalaPerson extends Person with Animal with HighAnimal {
var name:String = _
}
执行
val person = new ScalaPerson
person.name = "Alex"
ScalaPerson.testMethod()
person.move()
person.think()
println(person.getName())
结果:
运动
思考
null
这里的getName()方法源自父类Person。因此不是Alex。