scala中oop的学习


一、面向对象的基本概念

类(class)
抽象类(abstract class)
单例对象(object)
特质(trait)
样例类(case class)

示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

二、什么是类

类通过class关键字定义
类通过new关键字创建实例
类拥有成员变量和方法
类的成员默认为public,也支持private、protected
类中无法定义静态成员变量和方法
类无需明确定义构造方法,通过构造参数列表声明为类的一部分

三.类成员访问修饰符

在这里插入图片描述

四.类的定义

4.1构造器

  • 主构造器
  • 辅助构造器
  • 成员变量与方法
//主构造器执行类定义中的所有语句
class Point(xc: Int, yc: Int) {
    
    
  var x: Int = xc	//成员变量
  var y: Int = yc 
  //辅助构造器
  def this() ={
    
    
    this(0, 0)	//第一句必须调用其他构造器
  }
  //成员方法
  def move(dx: Int, dy: Int) ={
    
    
    x = x + dx
    y = y + dy
  }  
}

4.2类的实例化

var p=new Point()
p.x
p.y
p=new Point(12,11)
p.x
p.y
p.move(1,2)

五.类的继承

  • Scala使用“extends”关键字实现继承
  • 子类重写父类方法必须使用“override”关键字
class BlackPoint() extends Point {
    
    
    private var color="black"   
    override def move(dx: Int, dy: Int) ={
    
    
    x = x + dx
    y = y + dy
    println("moved to x:"+x+" y:"+y)
  }  
}

六.抽象类

  • 抽象类可包含未实现的方法,即抽象方法
  • 抽象类无法实例化
  • 抽象类使用“abstract”关键字修饰
  • 子类重写父类抽象方法时,“override”关键字可选
  • 子类重写父类非抽象方法,“override”关键字必写
abstract class Shape{
    
    
    def draw():Unit
}

class Square extends Shape{
    
    
    override def draw():Unit={
    
    
        println("draw a square")
    }
}
var shape=new Square
shape.draw

七.单例对象(object)

Scala的类中无法定义静态成员,即无static关键字。如何像Java一样表达类的静态成员变量、成员方法与静态代码块?
Scala解决方案:单例对象
使用“object”关键字声明,可包含变量、方法与代码定义
单例对象中的成员变量、成员方法通过单例对象名直接调用
单例对象第一次被访问时初始化,并执行全部代码块
单例对象不能new,且无构造参数
程序入口main()方法必须定义在单例对象中
单例对象与同名类定义在同一文件中时形成绑定关系

package test  //定义包名
//定义单例对象
object Blah {
    
    
  println("Blah initializing...")
  def sum(l: List[Int]): Int = l.sum
}
test.Blah.sum(List[Int](1, 2, 3, 4, 5))

八.伴生

  • 单例对象与同名类定义在同一文件中时形成绑定关系
  • 同名类称为单例对象的伴生类(class)
  • 单例对象称为同名类伴生对象(object)
  • 伴生类与伴生对象可相互访问各自私有成员
  • 伴生对象可为伴生类增加静态成员

8.1伴生类与伴生对象

//Student.scala
//伴生类
class Student(n: String, a: Int) {
    
    
  private var name = n    //私有变量,伴生对象可以访问
  private var age = a
}
//伴生对象
object Student {
    
    
  def apply(n: String, a: Int): Student = new Student(n, a)
  def main(args: Array[String]): Unit = {
    
    
    val stu=Student("Jason",9)  //通过伴生对象的apply()方法创建实例
    println(stu.name)
  }
}

九.特质(trait)

  • Scala中没有接口(interface)的概念
  • 特质用于在类之间共享程序接口和字段,类似Java接口
  • 特质是字段和方法的集合,可以提供字段和方法实现
  • 类和单例对象都可以扩展特质(extends)
  • 特质不能被实例化,因此没有构造参数,类似Java接口
  • 特质使用“trait”关键字定义
  • 实现特质中的方法使用“override”
import scala.collection.mutable.ArrayBuffer

trait Pet {
    
    
  val name: String
  def cry():Unit
}
class Dog(val name: String) extends Pet{
    
    
  override def cry()=println("wow ...")
}
val dog = new Dog("Harry")
val animals = ArrayBuffer.empty[Pet]
animals.append(dog)
animals.foreach(pet => {
    
    println(pet.name);pet.cry()})  // Prints Harry wow ...

十.混入特质

当某个特质被用于组合类时,被称为混入
一个类只能有一个父类但是可以有多个混入(分别使用关键字extends和with)

abstract class A {
    
    
  val message: String
}
class B extends A {
    
    
  val message = "I'm an instance of class B"
}
trait C extends A {
    
    
  def loudMessage = message.toUpperCase()
}
class D extends B with C

val d = new D
println(d.message)  // I'm an instance of class B
println(d.loudMessage)  // I'M AN INSTANCE OF CLASS B

10.1动态混入特质

this:Type=> 自身类型,表示该类实例化时必须混入相应特质或子特质,self是this的别名。

class Drawing {
    
     
  self: Shape =>  
  def start(): Unit = draw()
}
trait Shape {
    
    
  def draw(): Unit
}
trait Square extends Shape {
    
    
  def draw(): Unit = println("draw a square")
}
trait Triangle extends Shape {
    
    
  def draw(): Unit = println("draw a triangle")
}
//动态混入
(new Drawing() with Square).start()
(new Drawing() with Triangle).start()

十一.特质与抽象类的选择

优先使用特质
抽象类只能继承一次
特质可混入多个
需要使用带参构造方法时,使用抽象类
与Java互操作性

抽象类与Java完全可互操作
特质只有在不包含任何实现代码时才可互操作

十二.内部类

一个类可以作为另一个类的成员,称为内部类
Java内部类是外部类的成员
Scala内部类绑定到外部类的对象实例

class Graph {
    
    
  class Node {
    
    
    var connectedNodes: List[Graph#Node] = Nil
    def connectTo(node: Graph#Node) {
    
    
      if (connectedNodes.find(node.equals).isEmpty) {
    
    
        connectedNodes = node :: connectedNodes
      }
    }
  }
  var nodes: List[Node] = Nil
  def newNode: Node = {
    
    
    val res = new Node
    nodes = res :: nodes
    res
  }
}

val g: Graph = new Graph
val n1: g.Node = g.newNode
val n2: g.Node = g.newNode
n1.connectTo(n2)      // legal
val h: Graph = new Graph
val n3: h.Node = h.newNode
n1.connectTo(n3)      // illegal!

十三.样例类(case class)

样例类常用于描述不可变的值对象(Value Object)
样例类构造参数默认声明为“val”,自动实现类构造参数的getter
样例类构造参数声明为“var”时,自动实现类构造参数的setter和getter
样例类自动创建伴生对象
样例类自动实现的其他方法
toString()、equals()、copy()、hashCode()
伴生对象中的apply()、unapply()

case class Student(name:String,age:Int)      //定义样例类
val stu=Student("Jason",19)      //创建样例类的实例,无需new关键字
println(stu.name)       //访问对象属性         

猜你喜欢

转载自blog.csdn.net/weixin_44695793/article/details/108810880
OOP
今日推荐