大数据学习之Scala——04Scala面向对象编程(二)

一. 封装

1. 什么是封装
  • 封装(encapsulation)就是把抽象出的数据/属性和对数据的操作/方法封装在一起,数据被保护在内部,程序的其它部分只有通过被授权的操作(成员方法),才能对数据进行操作。
2. 封装的实现步骤
  1. 将属性进行私有化

  2. 提供一个公共的set方法,用于对属性判断并赋值:

    def  setXxx(参数名 : 类型) : Unit = {
    	//加入数据验证的业务逻辑
    	属性 = 参数名
    }
    
  3. 提供一个公共的get方法,用于获取属性的值

    def getXxx() [: 返回类型] = {      
    	//权限,需要自己.
    	return 属性
    }
    
3. 案例
  1. 自定义setter 和 getter

    object Test05 {
      def main(args: Array[String]): Unit = {
        val s1: Student = new Student("张三", 23, 34.5F)
        println(s1.getName())
        s1.setName("李四")
        println(s1.getName())
      }
    }
    
    class Student{
      private var name: String = _
      private var age: Int = _
      private var score: Float = _
    
      def this(xname: String, xage: Int, xscore: Float) {
        this()
        this.name = xname
        this.age = xage
        this.score = xscore
      }
    
      def setName(name: String): Unit = {
        this.name = name
      }
    
      def getName(): String = {
        name
      }
      def setAge(age: Int): Unit = {
        this.age = age
      }
    
      def getAge(): Int = {
        age
      }
    
      def setScore(score: Float): Unit = {
        this.score = score
      }
    
      def getScore(): Float = {
        score
      }
    
      override def toString = s"Student($name, $age, $score)"
    }
    
  2. 系统自动生成getter 和 setter

    object Test05 {
      def main(args: Array[String]): Unit = {
        val s1: Student = new Student("张三", 23, 34.5F)
        // 自动创建getter 和 setter
        println(s1.name)
        s1.name = "李四"
        println(s1.name)
      }
    }
    
    class Student{
      var name: String = _
      var age: Int = _
      var score: Float = _
    
      def this(xname: String, xage: Int, xscore: Float) {
        this()
        this.name = xname
        this.age = xage
        this.score = xscore
      }
      
      override def toString = s"Student($name, $age, $score)"
    }
    
4. Scala封装的注意事项和细节
  1. Scala中为了简化代码的开发,当声明属性时,本身就自动提供了对应setter/getter方法,如果属性声明为private的,那么自动生成的setter/getter方法也是private的,如果属性省略访问权限修饰符,那么自动生成的setter/getter方法是public的

  2. 因此我们如果只是对一个属性进行简单的set和get ,只要声明一下该属性(属性使用默认访问修饰符) 不用写专门的getset,默认会创建,访问时,直接对象.变量。这样也是为了保持访问一致性

二. 继承

1. 继承的基本语法
class 子类名 extends 父类名  { 
	// 类体 
}

2. Scala继承给编程带来的便利
  1. 代码的复用性提高了
  2. 代码的扩展性维护性提高了
3. scala子类继承了什么,怎么继承了?
  • 子类继承了所有的属性,只是私有的属性不能直接访问,需要通过从父类继承的公共的方法去访问
4. 重写方法(方法覆盖)

scala明确规定,重写一个非抽象方法需要用override关键字修饰,调用超类的方法使用super关键字

5. 案例
  1. 代码

    object Test05 {
      def main(args: Array[String]): Unit = {
        val s1: Student = new Student("张三", 23, 34.5F)
        println(s1)
        println(s1.name)
        println(s1.showType())
      }
    }
    
    class Student extends Person {
      var score: Float = _
      def this(xname: String, xage: Int, xscore: Float) {
        this()
        this.name = xname
        this.age = xage
        this.score = xscore
      }
    
      override def showType(): String = {
        "我是学生, 我的父类是" + super.showType()
      }
      
      override def toString = {
        s"Student(姓名: $name, 年龄: $age, 成绩: $score)"
      }
    }
    
    class Person {
      var name: String = _
      var age: Int = _
      def this(xname: String, xage: Int) {
        this()
        this.name = xname
        this.age = xage
      }
    
      def showType(): String = {
        "人类"
      }
    
      override def toString = s"Person($name, $age)"
    }
    
  2. 运行结果在这里插入图片描述

三. 多态

四.抽象类

1. 基本介绍
  • 在Scala中,通过abstract关键字标记不能被实例化的类。方法不用标记abstract,只要省掉方法体即可。抽象类可以拥有抽象字段,抽象字段/属性就是没有初始值的字段
2. 基本语法
  • abstract class 类名() {
    	...
    }
    
3. 案例
  • abstract class Student1() {
      var name: String = _
      var age: Int = _
      // 抽象类
      def printName()
      def show(): Unit = {
        print(s"名字是: $name, 年龄是: $age")
      }
    }
    
4. 注意事项
  1. 抽象类不能被实例化
  2. 抽象类不一定要包含abstract方法。也就是说,抽象类可以没有abstract方法
  3. 一旦类包含了抽象方法或者抽象属性,则这个类必须声明为abstract
  4. 抽象方法不能有主体,不允许使用abstract修饰。
  5. 如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法和抽象属性,除非它自己也声明为abstract类。
  6. 抽象方法和抽象属性不能使用private、final 来修饰,因为这些关键字都是和重写/实现相违背的。
  7. 抽象类中可以有实现的方法.
  8. 子类重写抽象方法不需要override,写上也不会错(另一种叫法是实现).

五. 静态属性和静态方法

1. 伴生对象

1. 背景
  • Scala语言是完全面向对象(万物皆对象)的语言,所以并没有静态的操作(即在Scala中没有静态的概念)。也没有static关键字, 但是为了能够和Java语言交互(因为Java中有静态概念),就产生了一种特殊的对象来模拟类对象,我们称之为类的伴生对象。这个类的所有静态内容都可以放置在它的伴生对象中声明和调用
2. 基本语法
  • 在这里插入图片描述
3. 小结
  1. Scala中伴生对象采用object关键字声明,伴生对象中声明的全是 "静态"内容,可以通过伴生对象名称直接调用。
  2. 伴生对象对应的类称之为伴生类,伴生对象的名称应该和伴生类名一致。
  3. 伴生对象中的属性和方法都可以通过伴生对象名直接调用访问
  4. 从语法角度来讲,所谓的伴生对象其实就是类的静态方法和静态变量的集合
  5. 从技术角度来讲,scala还是没有生成静态的内容,只不过是将伴生对象生成了一个新的类,实现属性和方法的调用。
  6. 从底层原理看,伴生对象实现静态特性是依赖于 public static final MODULE$ 实现的。
  7. 伴生对象的声明应该和伴生类的声明在同一个源码文件中(如果不在同一个文件中会运行错误!),但是如果没有伴生类,也就没有所谓的伴生对象了,所以放在哪里就无所谓了。
  8. 如果 class A 独立存在,那么A就是一个类, 如果 object A 独立存在,那么A就是一个"静态"性质的对象[即类对象], 在 object A中声明的属性和方法可以通过 A.属性 和 A.方法 来实现调用
  9. 在伴生对象中定义apply方法,可以实现: 类名(参数) 方式来创建对象实例.

六. 特质(trait)

Scala语言中,采用trait(特质,特征)来代替接口的概念,也就是说,多个类具有相同的特征(特征)时,就可以将这个特质(特征)独立出来,采用关键字trait声明。

1. trait的声明
  • trait 特质名 {
    	trait体
    }
    
    
2. trait的使用
  1. 没有父类

    class 类名 extends 特质1 with 特质2 with 特质3 ..
    
  2. 有父类

    class 类名 extends 父类 with 特质1 with 特质2 with 特质3
    
3. 说明
  1. Scala提供了特质(trait),特质可以同时拥有抽象方法和具体方法,一个类可以实现/继承多个特质。
  2. 特质中没有实现的方法就是抽象方法。类通过extends继承特质,通过with可以继承多个特质
  3. 所有的java接口都可以当做Scala特质使用
  4. 可以把特质可以看作是对继承的一种补充
    Scala的继承是单继承,也就是一个类最多只能有一个父类,这种单继承的机制可保证类的纯洁性, 比c++中的多继承机制简洁。但对子类功能的扩展有一定影响.所以 Scala引入trait特征 第一可以替代Java的接口, 第二个也是对单继承机制的一种补充

声明:

  1. 本文参考了尚硅谷Scala课程的课件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值