1. 什么是面向对象
面向对象(Object Oriented)是软件开发方法,一种编程范式,面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物。 我们经常说Java是一种面向对象的语言,其中三大特性为:封装、继承、多态。
2. Scala class的使用
2.1 创建一个简单的类
class SimpleClass {
val name: String = "spark"
var age: Int = _
def eat( ) : Unit = {
println( s"$name eat" )
}
}
2.2 在Linux上面进行编译
[ root@bigdatatest01 scala]
/root/script/scala
[ root@bigdatatest01 scala]
class SimpleClass {
val name: String = "spark"
var age: Int = _
def eat( ) : Unit = {
println( s"$name eat" )
}
}
[ root@bigdatatest01 scala]
[ root@bigdatatest01 scala]
SimpleClass.class SimpleClass.scala
2.3 反编译Class
[ root@bigdatatest01 scala]
Compiled from "SimpleClass.scala"
public class SimpleClass {
private final java.lang.String name;
public java.lang.String name( ) ;
private int age;
public int age( ) ;
public void age_$eq ( int) ;
public void eat( ) ;
public SimpleClass( ) ;
}
val name 对应private final java.lang.String name; public java.lang.String name();只能从这个类中得到name这个属性的数据,无法修改name 这个属性的数据。 var age:对应private int age; public int age(); public void age_$eq(int); 可以从此类中得到age数据,并且可以修改age数据。
2.4 SimpleClassApp Code
package com. xk. bigdata. scala. oo
object SimpleClassApp {
def main( args: Array[ String ] ) : Unit = {
val simpleClass = new SimpleClass
simpleClass. age_$eq( 16 )
println( s"${simpleClass.name}========>${simpleClass.age}" )
simpleClass. eat( )
}
}
class SimpleClass {
val name: String = "spark"
var age: Int = _
def eat( ) : Unit = {
println( s"$name eat" )
}
}
new $类名,调用的是此类的构造器,由于每个类都会默认一个空构造器,所以可以省略类名后面的括号。 从上面反编译可以看出来,
对
象
.
对象.
对 象 . 属性_
e
q
(
eq(
e q ( 数据)相当于Java中的set,可以把数据传输到这个对象的属性当中。
3. 构造器的使用
Scala中的构造器分为主构造器、附属构造器 主构造器:定义方式:class $类名(val $属性名称: $属性类型),主构造器的定义是在Class后面来定义的,修饰符使用 val 来修饰,如果不使用 val 修饰符,对象则无法调用这个属性。 附属构造器:def this($入参参数名: $入参参数类型),附属构造器一般是调用其他的附属构造器或者主构造器。
package com. xk. bigdata. scala. oo
object ConstructApp {
def main( args: Array[ String ] ) : Unit = {
val person = new Person( "hadoop" , 21 , "A" )
println( person. school)
}
class Person( val name: String , val age: Int ) {
var school: String = _
def this ( name: String , age: Int , school: String ) {
this ( name, age)
this . school = school
}
}
}
4. 继承的使用
在Scala中使用继承和Java中是一样,使用extends关键字,Java中Class只有单继承,接口可以多继承,而Scala中可以多继承,Scala 的trait 类似于Java中的接口,无论是trait还是子类,都是通过 extends + with 来实现,实现类或者接口数量大于三个,并且类或者trait通过先后顺序进行加载。 如果需要重写父类的属性或者方法,需要在属性或者方法前面加上 override 关键字。 new 一个子类一定会先加载父类的构造器,然后加载子类的构造器。
package com. xk. bigdata. scala. oo
object ExtendsApp {
def main( args: Array[ String ] ) : Unit = {
val student = new Student( "spark" , 15 , "A" )
student. eat( )
println( student. gender)
}
class Person( val name: String , val age: Int ) {
val gender = "M"
def eat( ) : Unit = {
println( s"Person Class $name........eat" )
}
}
class Student( name: String , age: Int , val school: String ) extends Person( name, age) {
override val gender: String = "L"
override def eat( ) : Unit = {
println( s"Student Class $name........eat" )
}
}
}
5. 抽象类
抽象类定义的时候需要有一个或者多个没有实现的方法,只是定义了方法,没有具体实现。 抽象类只需要类名前面加 abstract 关键词,属性以及方法前面不需要添加 abstract 关键词。 抽象类使用: 1) 显示定义 2)匿名子类
package com. xk. bigdata. scala. oo
object AbstractClassApp {
def main( args: Array[ String ] ) : Unit = {
val student = new Student( "hadoop" , 20 )
student. speak
val student2 = new Person( "spark" , 21 ) {
override def speak: Unit = {
println( s"$name is speak" )
}
}
student2. speak
}
abstract class Person( val name: String , val age: Int ) {
def speak: Unit
}
class Student( name: String , age: Int ) extends Person( name, age) {
override def speak: Unit = {
println( s"$name is speak" )
}
}
}
6. Trait
Scala 中 Trait 相当于Java中的接口,不同于接口的地方是,Trait 还可以定义属性和方法,一般情况下,Scala只能继承单一父类,但是可以继承多个 Trait,从结果来看,Scala实现了多重继承。 Trait 定义方式:使用 trait 关键词。 Trait 多重继承通过 extends 和 with 关键词来进行继承。
package com. xk. bigdata. scala. oo
object TraitApp {
def main( args: Array[ String ] ) : Unit = {
val miUSB = new MiUSB
println( miUSB. name)
miUSB. plugIn
miUSB. insert
miUSB. working
}
trait USB {
println( "========USB======" )
val name: String
def insert
def working
def pop
}
trait Logger {
println( "========Logger======" )
def loginfo
}
trait Socket {
println( "========Socket======" )
def plugIn
}
class MiUSB extends Logger with USB with Socket {
override def loginfo: Unit = {
println( "loginfo=====>MiUSB" )
}
override val name: String = "小米充电器"
override def insert: Unit = {
println( "接入充电器" )
}
override def working: Unit = {
println( "充电器开始工作" )
}
override def pop: Unit = {
println( "充电完成,拔出!!" )
}
override def plugIn: Unit = {
println( "插上插座" )
}
}
}
7. Case Class
Case Class 和 Class 的区别:
初始化的时候可以不用new,也可以加上,但是普通类必须加new。 默认实现了equals、hashCode方法。 默认是可以序列化的,实现了Serializable。 自动从scala.Product中继承一些函数。 case class 构造函数参数是public的,我们可以直接访问。 case class默认情况下不能修改属性值。 case class最重要的功能,支持模式匹配,这也是定义case class的重要原因 Case Class 和 Class 最大的区别就是 Case Class 重写了 equals、hashcode、tostring方法。 重写 equals和hashcode 最大的表现就是两个属性值一样的对象是相等的,说明 Case Class 底层判断两个对象是否相等,判断的是对象里面的每个属性数据是否相等。 重写 tostring 表现在 打印 Case Class 对象的时候打印出来的出现数据,打印 Class 对象的信息,打印的是内存地址。 当使用 case class 的时候,Scala 会帮我们做如下几个事情:
构造器中的参数如果不被声明为var的话,它默认的话是val类型的,但一般不推荐将构造器中的参数声明为var。 自动创建伴生对象,同时在里面给我们实现子apply方法,使得我们在使用的时候可以不直接显示地new对象。 伴生对象中同样会帮我们实现unapply方法,从而可以将case class应用于模式匹配。 实现自己的toString、hashCode、copy、equals方法。
package com. xk. bigdata. scala. oo
object CaseClassApp {
def main( args: Array[ String ] ) : Unit = {
val person1 = new Person1( "hadoop" , 18 )
val person2 = new Person1( "hadoop" , 18 )
println( person1. toString)
println( person1 == person2)
val person3 = Person2( "hadoop" , 18 )
val person4 = Person2( "hadoop" , 18 )
println( person3. toString)
println( person3 == person4)
}
class Person1( val name: String , val age: Int )
case class Person2( name: String , age: Int )
}
8. Class 和 Object
Class 和 Object 的关系:
对象不能带参数,类可以。 对象可以和类名一样时,object被称为伴生对象,class被称为伴生类。 类和伴生对象可以相互访问其私有属性,但是它们必须在一个源文件当中。 类只会被编译,不会被执行。要执行,必须在Object中。 Class 和 Object 的区别:
Class 在调用的时候需要 new 一个对象,通过对象去调用Class里面的属性或方法。 Object 在调用的时候不需要 new 一个对象,可以直接调用 Object里面的属性和方法。 同一个包下面的、名称相同的 Class 和 Object 互为伴生,Class为Object的伴生类, Object 为 Class 的伴生对象。 在调用伴生对象的后面加上括号,相当于调用伴生对象里面的 apply 方法,通常可以在 apply 方法里面 new 一个伴生类。 如果想一口气得到伴生类里面的所有属性,可以通过伴生对象的 unapply 方法来得到所有的属性。
package com. xk. bigdata. scala. oo
object ClassObjectApp {
def main( args: Array[ String ] ) : Unit = {
val person1 = new Person( "hadoop" , 21 )
person1. eat( )
val person2 = Person( "hadoop" , 21 )
person2. eat( )
val Person( name, age) = Person( "hadoop" , 21 )
println( s"name:$name==========age:$age" )
}
}
object Person {
def apply( name: String , age: Int ) : Person = {
println( "调用 object Person 的 apply 方法" )
new Person( name, age)
}
def unapply( arg: Person) : Option[ ( String , Int ) ] = {
println( "调用 object Person 的 unapply 方法" )
Option( arg. name, arg. age)
}
}
class Person( val name: String , val age: Int ) {
def eat( ) : Unit = {
println( s"$name is eat" )
}
}
9. Case Class 和 Case Object
Case Class 、 Case Object 的区别:
类中有参和无参,当类有参数的时候,用case class ,当类没有参数的时候那么用case object。
package com. xk. bigdata. scala. oo
object CaseClassCaseObjectApp {
def main( args: Array[ String ] ) : Unit = {
val person1 = new Per( "hadoop" , 18 )
person1. eat( )
Per. eat( )
}
}
case class Per( name: String , age: Int ) {
def eat( ) : Unit = {
println( "case class Person eat" )
println( s"$name is eat" )
}
}
case object Per {
def eat( ) : Unit = {
println( "case object Person eat" )
println( "eat" )
}
}