欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[Scala] Scala 学习笔记 (10) - 面向对象 (待补充)

程序员文章站 2022-06-14 22:35:49
...

Scala面向对象

1. 类 class

类的定义

// 定义一个类
class People {

  // 定义属性
//  var name:String = ""
  var name:String = _   // name这里也可以直接使用占位符占位
  val age = 10
  private[this] val gender = "M"   // gender是类People的一个私有属性,在外面是不能直接被调用的

  def printInfo(): Unit = {
    println(gender)
  }

  // 定义方法
  def eat() = {
    name + " eat banana."
  }

}

类的调用:如果要调用一个class类,要先new一个class出来

object SimpleClassApp {

  def main(args: Array[String]): Unit = {

    // 类的调用
    // new 一个类出来
    val people = new People
    people.name = "scala"

//    println(people.gender)   // gender是私有属性,不能直接调用
    people.printInfo()  // 但是gender在这里是被class本身调用,可以合法使用

    val a = people.eat()
    println(a)
  }

}

2. 构造函数

主构造函数:构造函数的入参都可以作为class的属性来使用。

附属构造函数:第一行必须调用主构造器或者其他附属构造器;附属构造函数可以写一个或者多个。

object ConstructApp {

  def main(args: Array[String]): Unit = {

    // 创建一个对象
    val girl = new Girl("Cindy", 18,"13000000000","somewhere")
    println(girl.name + " : " + girl.age + " : " + girl.phone + " : " + girl.address)

    girl.like()

    println(girl.city)
  }

}

// 构造函数中的参数以及类中的属性(非private的)都能直接能够当做对象的属性来使用
class Girl(val name:String, val age:Int) {
  println("girl enter")

  def like(): Unit = {
    println(name + " like something.")
  }

  val city = "Shenzhen"

  // 附属构造函数:第一行必须调用主构造器或者其他的附属构造器
  var phone = ""
  def this(name:String, age:Int, phone:String) {
    this(name,age)    // 第一行,调用主构造器
    this.phone
  }

  // 再定义一个附属构造函数
  var address = ""
  def this(name:String, age:Int, phone:String, address:String) {
    this(name,age,phone)  // 这里的phone在前面的附属构造函数里面已经定义了,可以直接使用
    this.address
  }

  println("girl exit")

}

3. 类的继承

3.1 发生继承时,当外面创建子对象的时候,首先会调用父类的构造方法,然后才是调用子类的构造方法;

    如果子类里面的属性不是父类里面已经有的,前面要加val修饰符,否则外面是访问不到的

创建一个子类,继承上面的Girl类

// 类的继承
/**
  *
  * 类的继承
  * littleGirl的前半部分littleGirl(name:String, age:Int)是一个主构造器,
  * 继承了Girl这个class
  * 并且littleGirl还加入了自己的参数major
  *
  * 发生继承时,当我们创建子对象的时候,首先会调用父类的构造方法,然后才是调用子类的构造方法
  * 如果子类里面的属性不是父类里面已经有的,前面要加val修饰符,否则外面是访问不到的
  */
class littleGirl(name:String, age:Int, val major :String) extends Girl(name,age) {

  println("littleGirl enter")


  println("littleGirl exit")
}

调用这个子类

    val littlegirl = new littleGirl("girl", 10, "computer")
    println(littlegirl.name + " : " + littlegirl.age + " : "  + littlegirl.major)

3.2  继承是发生在子类和父类之间的

如果想重写弗雷中已有的方法时,一定要添加override修饰符。

class littleGirl(name:String, age:Int, val major :String) extends Girl(name,age) {

  println("littleGirl enter")

  // toString是scala内置的一个object类的方法,如果想重写父类中已有的方法时,一定需要添加override修饰符
  override def toString = "littleGirl toString"


  println("littleGirl exit")

3.3 抽象类

类中有一个或者多个方法没有实现,换句话说:只有定义,没有实现。

这个抽象类是不能直接使用的,必须要通过实现了该抽象类的属性或者方法来使用。

子类重写父类中的属性或者方法,override可以不写。

定义一个抽象类

/**
  * 抽象类的定义 abstract
  * 抽象类可以有属性,有方法
  * 属性和方法都只是定义,没有实现
  * 这样的抽象类是不能直接被使用的
  */
abstract class Animal {
  // 属性或方法只有定义没有实现
  var name:String
  var age:Int
  def speak
}

因为这个抽象类不能直接使用,再定义一个子类继承上面的抽象类

/**
  * 定义一个字类继承上面的抽象类,这个子类要么再被定义成抽象类,或者实现父类的spark方法
  * 在Dog上面按住ctrl+回车,选择实现这个方法(Implement methods),选中所有的方法点OK
  * 再给属性赋值,方法重写
  * 子类重写父类中的方法或者属性,override可以省略不写
  */
class Dog extends Animal {
  
  // 重写父类的属性
  override var name: String = "Rich"
  override var age: Int = 1

  // 重写父类的方法
  override def speak: Unit = {
    println("wang wang wang")
  }
}

最后再调用这个子类,此时子类的属性和方法都可以被调用。

object AbstractApp {

  def main(args: Array[String]): Unit = {

    // 因为抽象类Animal是不能直接被使用的,所以new一个它的子类,再调用它的方法
    val dog = new Dog
    dog.speak
  }

}

 

 

思考:

抽象类的用途是什么?

相关标签: scala 面向对象