【Scala】面向对象

1 类与对象

  • 创建类的语法格式
class ClassName[parameterList]
  • 创建对象的语法格式
ClassName objectName = new ClassName();

例1:定义一个Point类

class Point(a: Int, b: Int) {
  var x = a
  var y = b
  def move(dx: Int, dy: Int): Unit = {
    x += dx
    y += dy
    println("x: " + x)
    println("y: " + y)
  }
}
object PointTest {
  def main(args: Array[String]): Unit = {
    val point = new Point(2, 3)
    point.move(10, 21)
  }
}

2 构造器

例1也可以取消参数列表,改写成有构造器

class Point {
  var x = 0
  var y = 0

  def this(a: Int, b: Int) {
    this()
    x = a
    y = b
  }
    
  def move(dx: Int, dy: Int): Unit = {
    x += dx
    y += dy
    println("x: " + x)
    println("y: " + y)
  }
}

例2:自定义计数器,使用多重构造器

class Counter {
  private var value = 0
  private var name = "Default"
  private var mode = 0

  def this(name: String) {
    this()
    this.name = name
  }

  def this(name: String, mode: Int) {
    this(name)
    this.mode = mode
  }

  def increment(step: Int): Unit = value += step

  def current(): Int = value

  def info(): Unit = {
    printf("Name: %s, Mode: %d\n", name, mode)
  }
}

object CounterTest {
  def main(args: Array[String]): Unit = {
    val myCounter = new Counter
    val runnerCounter = new Counter("Runner")
    val timerCounter = new Counter("Timer", 2)

    myCounter.info
    myCounter.increment(1)
    println(myCounter.current())

    runnerCounter.info
    runnerCounter.increment(2)
    println(runnerCounter.current())

    timerCounter.info()
    timerCounter.increment(3)
    println(timerCounter.current())
  }
}

3 get和set

class Counter {
  private var privateValue = 0

  // scala的get方法
  def value = privateValue
    
  // scala的set方法
  def value_=(newValue: Int): Unit = {
    if (newValue > 0) privateValue = newValue
  }

  def increment(step: Int): Unit = value += step // 只有一行可以去掉大括号
  def increment(): Unit = value += 1

  def current(): Int = value // 把value作为返回值

}

object CounterTest {
  def main(args: Array[String]): Unit = {
    val myCounter = new Counter

    // 调用无参数increment
    myCounter.increment
    println(myCounter.current)

    // 调用set方法
    myCounter.value = 2
    // 调用get方法
    println(myCounter.value)

    // 调用有参数increment
    myCounter.increment(2)
    println(myCounter.current)
  }
}

4 单例对象与伴生对象

  • 单例对象
object Hello {
  def main(args: Array[String]): Unit = {
    println("Hello World!")
  }
}
  • 伴生对象
class Person {
  private val id = Person.newPersonId()
  private var name = ""
  def this(name: String) {
    this()
    this.name = name
  }
  def info() {printf("The id of %d is %s.\n", id, name)}
}

// 与class同名的object 则该object是同名class的伴生对象
object Person {
  private var lastId = 0
  
  // 反编译后可知这是一个static方法 
  private def newPersonId() = {
    lastId += 1
    lastId
  }
  def main(args: Array[String]): Unit = {
    val p1 = new Person("Ziyu")
    val p2 = new Person("Minxing")
    p1.info()
    p2.info()
  }
}

5 Apply方法

apply方法自动调用

class ApplyTest {
  def apply() {
    println("apply method in class is called!")
  }
  def greetingOfClass: Unit = {
    println("Greeting method in class is called!")
  }
}

object ApplyTest {
  def apply(): ApplyTest = {
    println("apply method in object is called!")
    new ApplyTest()
  }
    
  def main(args: Array[String]): Unit = {
    // 调用伴生对象的apply方法,返回一个伴生类的对象
    val a = ApplyTest()

    a.greetingOfClass
    // a已经是实例对象,调用伴生类的apply方法
    a()

    // b本来就是实例对象
    val b = new ApplyTest
    b()
  }
}
  • Array的apply方法
val myArr = Array("Hadoop")
// ctrl 点击Array进去有新发现
// object Array 下的 apply 方法
def apply[T: ClassTag](xs: T*): Array[T] = {
    val len = xs.length
    xs match {
        case wa: mutable.WrappedArray[_] if wa.elemTag == classTag[T] =>
        // We get here in test/files/run/sd760a.scala, `Array[T](t)` for
        // a specialized type parameter `T`. While we still pay for two
        // copies of the array it is better than before when we also boxed
        // each element when populating the result.
        	ScalaRunTime.array_clone(wa.array).asInstanceOf[Array[T]]
        case _ =>
            val array = new Array[T](len)
            var i = 0
            for (x <- xs.iterator) { array(i) = x; i += 1 }
            array
    }
}
// 可以看到新建了一个array类的实例对象并返回给myArr

6 Update方法

object TestUpdateClass {
  def main(args: Array[String]): Unit = {
    val myArr = Array(1, 2, 3)
      
    // 调用myArr.update(0, 0)
    myArr(0) = 0
  }
}

现在可以初步理解为什么scala数组访问用圆括号了

7 抽象类

  • 变量可以没有定义
  • 方法可以没有定义
abstract class car {
  val carBand: String
  def info()
  def greeting(): Unit = {
    println("Welcome to my car!")
  }
}

8 继承

接上一节抽象类

class BMWcar extends car {
  // 这个override可以没有,因为父类没有给出变量定义
  override val carBand: String = "BMO"

  // 父类没有给方法定义,所以可以不用override
  def info(): Unit = {
    printf("This is a %s car.\n", carBand)
  }

  // 重写父类方法需要用override
  override def greeting(): Unit = {
    println("Welcome to my BMW car! It is cheap!")
  }
}

class BYDcar extends car {
  override val carBand: String = "BYD"

  def info(): Unit = {
    printf("This is a %s car. It is expensive.\n", carBand)
  }

  override def greeting(): Unit = {
    println("Welcome to my BYD car!")
  }
}

object TestCar {
  def main(args: Array[String]): Unit = {
    val car1 = new BMWcar
    val car2 = new BYDcar
      
    car1.greeting()
    car1.info()
      
    car2.greeting()
    car2.info()
  }
}

9 特质trait

// 特质1 CarId
trait CarId {
  var id: Int
  def currentId(): Int
}

// 特质2 CarGreeting
trait CarGreeting {
  def greeting(msg: String) {println(msg)}
}

// 继承上面两个特质 用with
class BYDCarId extends CarId with CarGreeting {
  var id = 10000
  def currentId(): Int = {id += 1; id}
}

// 可以不用override 因为trait没有实现
class BMWCarId extends CarId with CarGreeting {
  var id: Int = 20000
  override def currentId(): Int = {
    id += 1
    id
  }
}

object Test {
  def main(args: Array[String]): Unit = {
    val carId1 = new BYDCarId
    val carId2 = new BMWCarId
      
    carId1.greeting("Welcome to my first car!")
    printf("My first CarId is %d.\n", carId1.currentId())
      
    carId2.greeting("Welcome to my second car!")
    printf("My second CarId is %d.\n", carId2.currentId())
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值