Chiriri's blog Chiriri's blog
首页
  • Java

    • JavaSE
    • JavaEE
    • 设计模式
  • Python

    • Python
    • Python模块
    • 机器学习
  • Golang

    • Golang
    • gRPC
  • 服务器

    • Linux
    • MySQL
    • NoSQL
    • Kubernetes
  • 项目

    • 传智健康
    • 畅购商城
  • Hadoop生态

    • Hadoop
    • Zookeeper
    • Hive
    • Flume
    • Kafka
    • Azkaban
    • Hbase
    • Scala
    • Spark
    • Flink
  • 大数据项目

    • 离线数仓
  • 青训营

    • 第四届青训营
  • HTML

    • HTML
    • JavaScript
  • Vue

    • Vue2
    • TypeScript
    • Vue3
    • Uni-APP
  • 数据结构与算法
  • C语言
  • 考研数据结构
  • 计算机组成原理
  • 计算机操作系统
  • Java基础

    • Java基础
    • Java集合
    • JUC
    • JVM
  • 框架

    • Spring
    • Dubbo
    • Spring Cloud
  • 数据库

    • MySQL
    • Redis
    • Elasticesearch
  • 消息队列

    • RabbitMQ
    • RocketMQ
  • 408

    • 计算机网络
    • 操作系统
    • 算法
  • 分类
  • 标签
  • 归档
  • 导航站
GitHub (opens new window)

Iekr

苦逼后端开发
首页
  • Java

    • JavaSE
    • JavaEE
    • 设计模式
  • Python

    • Python
    • Python模块
    • 机器学习
  • Golang

    • Golang
    • gRPC
  • 服务器

    • Linux
    • MySQL
    • NoSQL
    • Kubernetes
  • 项目

    • 传智健康
    • 畅购商城
  • Hadoop生态

    • Hadoop
    • Zookeeper
    • Hive
    • Flume
    • Kafka
    • Azkaban
    • Hbase
    • Scala
    • Spark
    • Flink
  • 大数据项目

    • 离线数仓
  • 青训营

    • 第四届青训营
  • HTML

    • HTML
    • JavaScript
  • Vue

    • Vue2
    • TypeScript
    • Vue3
    • Uni-APP
  • 数据结构与算法
  • C语言
  • 考研数据结构
  • 计算机组成原理
  • 计算机操作系统
  • Java基础

    • Java基础
    • Java集合
    • JUC
    • JVM
  • 框架

    • Spring
    • Dubbo
    • Spring Cloud
  • 数据库

    • MySQL
    • Redis
    • Elasticesearch
  • 消息队列

    • RabbitMQ
    • RocketMQ
  • 408

    • 计算机网络
    • 操作系统
    • 算法
  • 分类
  • 标签
  • 归档
  • 导航站
GitHub (opens new window)
  • Hadoop

  • Zookeeper

  • Hive

  • Flume

  • Kafka

  • Azkaban

  • Hbase

  • Scala

    • Scala介绍
    • Scala入门
    • 流程控制
    • 函数式编程
    • 面向对象
      • 包
        • 嵌套声明包
        • 包对象
        • 导包
      • 类和对象
        • 定义类
        • 属性和封装
        • 访问权限
        • 构造器
        • 构造器参数
        • 继承
        • 抽象属性和抽象方法
        • 继承和重写
        • 动态绑定
        • 匿名子类
  • Spark

  • Flink

  • 离线数仓

  • 青训营

  • DolphinScheduler

  • Doris

  • 大数据
  • Scala
Iekr
2021-12-15
目录

面向对象

# 面向对象

# 包

# 嵌套声明包

Scala 有两种包的管理风格,其中一种方式和 Java 的包管理风格相同,还有一种是嵌套声明

package com{
	package atguigu{
		package scala{

		}
	}
}
1
2
3
4
5
6
7

第二种风格有以下特点:

  1. 一个源文件中可以声明多个 package
  2. 子包中的类可以直接访问父包中的内容,而无需导包
package com {

    import com.atguigu.Inner //父包访问子包需要导包

    object Outer {
        val out: String = "out"

        def main(args: Array[String]): Unit = {
            println(Inner.in)
        }
    }

    package atguigu {

        object Inner {
            val in: String = "in"

            def main(args: Array[String]): Unit = {
                println(Outer.out) //子包访问父包无需导包
            }
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 包对象

在 Scala 中可以为每个包定义一个同名的包对象,定义在包对象中的成员,作为其对应包下所有 class 和 object 的共享变量,可以被直接访问。

package object com{
	val shareValue="share"
	def shareMethod()={}
}
1
2
3
4

嵌套方式管理包,则包对象可与包定义在同一文件中,但是要保证包对象与包声明在同一作用域中。

package com {

    object Outer {
        val out: String = "out"

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

package object com {
    val name: String = "com"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 导包

  1. 和 Java 一样,可以在顶部使用 import 导入,在这个文件中的所有类都可以使用。
  2. 局部导入:什么时候使用,什么时候导入。在其作用范围内都可以使用
  3. 通配符导入:import java.util._
  4. 给类起名:import java.util.{ArrayList=>JL}
  5. 屏蔽类:import java.util.{ArrayList =>,}
  6. 导入相同包的多个类:import java.util.{HashSet, ArrayList}
  7. 导入包的绝对路径:new _root_.java.util.HashMap
import com.atguigu.Fruit 引入 com.atguigu 包下 Fruit(class 和 object)
import com.atguigu._ 引入 com.atguigu 下的所有成员
import com.atguigu.Fruit._ 引入 Fruit (object) 的所有成员
import com.atguigu.{Fruit,Vegetable} 引入 com.atguigu 下的 Fruit 和 Vegetable
import com.atguigu.{Fruit=>Shuiguo} 引入 com.atguigu 包下的 Fruit 并更名为 Shuiguo
import com.atguigu.{Fruit=>Shuiguo,_} 引入 com.atguigu 包下的所有成员,并将 Fruit 更名为 Shuiguo
import com.atguigu.{Fruit=>,} 引入 com.atguigu 包下屏蔽 Fruit 类
new _root_.java.util.HashMap 引入的 Java 的绝对路径

# 类和对象

类:可以看成一个模板

对象:表示具体的事物

# 定义类

一般,一个.java 有一个 public 类

Scala 中没有 public,一个.scala 中可以写多个类。

  1. Scala 语法中,类并不声明为 public,所有这些类都具有公有可见性(即默认就是 public)
  2. 一个 Scala 源文件可以包含多个类
object code05 {

  def main(args: Array[String]): Unit = {
    val student = new Student05
    println(student.name)
  }

}


class Student05{
  var name = "zhangsan"


}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 属性和封装

底层生成的字节码文件对属性使用的是 private 进行修饰,我们通过对象。属性名调用的是 java 中方法,方法名为属性名()即 getXxx()方法

image-20220604100650070

如果想要实现 JavaBean 规范的 get|set 方法需要要属性上加 @BeanPropetry 注解 可以自动生成规范的 setXxx/getXxx 方法

object code05 {

  def main(args: Array[String]): Unit = {
    val student = new Student05
    println(student.age)
  }

}


class Student05{
  var height: Int = _ // _表示给属性一个该类型的默认值 

  @BeanProperty
  var  age = 18

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

val 修饰的属性不能赋默认值,必须显示指定值

 val height: Int = _ //此时被赋值为0 无法再次修改
1

image-20220604101229992

如果在属性前加上 private 关键字 不光属性被私有连方法都会被私有

private var name = "zhangsan"
1

image-20220604101837748

# 访问权限

在 Java 中,访问权限分为:public,private,protected 和默认。在 Scala 中,你可以通过类似的修饰符达到同样的效果。但是使用上有区别。

  1. Scala 中属性和方法的默认访问权限为 public,但 Scala 中无 public 关键字。
  2. private 为私有权限,只在类的内部和伴生对象中可用。
  3. protected 为受保护权限,Scala 中受保护权限比 Java 中更严格,同类、子类可以访问,同包无法访问。
  4. private [包名] 增加包访问权限,包名下的其他类也可以使用
package com.atguigu.scala.test

class Person {

    private var name: String = "bobo"
    protected var age: Int = 18
    private[test] var sex: String = "男"

    def say(): Unit = {
        println(name)
    }
}


object Person {

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

        val person = new Person

        person.say()

        println(person.name)

        println(person.age)
    }
}


class Teacher extends Person {

    def test(): Unit = {
        this.age
        this.sex
    }
}

class Animal {
    def test: Unit = {
        new Person().sex
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

# 构造器

和 Java 一样,Scala 构造对象也需要调用构造方法,并且可以有任意多个构造方法。

Scala 类的构造器包括:主构造器和辅助构造器

class 类名(形参列表) {  
   // 主构造器 就在这个类中
    
   // 类体
   def  this(形参列表) {  // 辅助构造器
   }
   def  this(形参列表) {  //辅助构造器可以有多个...
   }
} 

1
2
3
4
5
6
7
8
9
10
  1. 辅助构造器,函数的名称 this,可以有多个,编译器通过参数的个数及类型来区分。
  2. 辅助构造方法不能直接构建对象,必须直接或者间接调用主构造方法。
  3. 构造器调用其他另外的构造器,要求被调用构造器必须提前声明。
//(1)如果主构造器无参数,小括号可省略
//class Person (){
class Person {
    println("主构造器")

    var name: String = _

    var age: Int = _

    def this(age: Int) {
        this()
        this.age = age
        println("辅助构造器")
    }

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

}

object Person {

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

        val person2 = new Person(18)
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# 构造器参数

Scala 类的主构造器函数的形参包括三种类型:未用任何修饰、var 修饰、val 修饰

  1. 未用任何修饰符修饰,这个参数就是一个局部变量
  2. var 修饰参数,作为类的成员属性使用,可以修改
  3. val 修饰参数,作为类只读属性使用,不能修改
class Person(name: String, var age: Int, val sex: String) {

}

object Test {

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

        var person = new Person("bobo", 18, "男")

        // (1)未用任何修饰符修饰,这个参数就是一个局部变量
        // printf(person.name)

        // (2)var修饰参数,作为类的成员属性使用,可以修改
        person.age = 19
        println(person.age)

        // (3)val修饰参数,作为类的只读属性使用,不能修改
        // person.sex = "女"
        println(person.sex)
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 继承

class 子类名 extends 父类名 { 类体 }

  1. 子类继承父类的属性和方法
  2. scala 是单继承
  3. 继承的调用顺序:父类构造器 -> 子类构造器
class Person(nameParam: String) {

    var name = nameParam
    var age: Int = _

    def this(nameParam: String, ageParam: Int) {
        this(nameParam)
        this.age = ageParam
        println("父类辅助构造器")
    }

    println("父类主构造器")
}


class Emp(nameParam: String, ageParam: Int) extends Person(nameParam, ageParam) {

    var empNo: Int = _

    def this(nameParam: String, ageParam: Int, empNoParam: Int) {
        this(nameParam, ageParam)
        this.empNo = empNoParam
        println("子类的辅助构造器")
    }

    println("子类主构造器")
}

object Test {
    def main(args: Array[String]): Unit = {
        new Emp("z3", 11,1001)
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 抽象属性和抽象方法

  1. 定义抽象类:abstract class Person {} 通过 abstract 关键字标记抽象类
  2. 定义抽象属性:val|var name:String 一个属性没有初始化,就是抽象属性
  3. 定义抽象方法:def hello ():String 只声明而没有实现的方法,就是抽象方法
abstract class Person { //通过abstract关键字标记抽象类

    val name: String //一个属性没有初始化,就是抽象属性

    def hello(): Unit //只声明而没有实现的方法,就是抽象方法
}

class Teacher extends Person {

    val name: String = "teacher"

    def hello(): Unit = {
        println("hello teacher")
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 继承和重写

  1. 如果父类为抽象类,那么子类需要将抽象的属性和方法实现,否则子类也需声明为抽象类
  2. 重写非抽象方法需要用 override 修饰,重写抽象方法则可以不加 override。
  3. 子类中调用父类的方法使用 super 关键字
  4. 子类对抽象属性进行实现,父类抽象属性可以用 var 修饰; 子类对非抽象属性重写,父类非抽象属性只支持 val 类型,而不支持 var。 因为 var 修饰的为可变变量,子类继承之后就可以直接使用,没有必要重写
  5. Scala 中属性和方法都是动态绑定,而 Java 中只有方法为动态绑定,属性为静态绑定 (编译看左,运行看右)。
class Person {
    val name: String = "person"

    def hello(): Unit = {
        println("hello person")
    }
}

class Teacher extends Person {

    //可以对非抽象属性重写 如果是可变变量并且有值不推荐重写
    override val name: String = "teacher"
    //val name: String = "teacher" //不使用override关键字同样可以重写属性

    //override def hello(): Unit = {} //不使用override关键字同样可以重写方法  
    
    //如果不是抽象方法重写必须要使用override关键字
    override def hello(): Unit = {
        //super.hello() //可以通过super.方法名()调用原父类方法
        println("hello teacher")
    }
}

object Test {
    def main(args: Array[String]): Unit = {
        val teacher: Teacher = new Teacher()
        println(teacher.name)
        teacher.hello()

        val teacher1:Person = new Teacher
        println(teacher1.name)
        teacher1.hello()
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

# 动态绑定

Scala 中属性和方法都是动态绑定,而 Java 中只有方法为动态绑定,属性为静态绑定 (编译看左,运行看右)。

Java

class Person {

    public String name = "person";
    public void hello() {
        System.out.println("hello person");
    }

}
class Teacher extends Person {

public String name = "teacher";

    @Override
    public void hello() {
        System.out.println("hello teacher");
    }

}
public class TestDynamic {
public static void main(String[] args) {

        Teacher teacher = new Teacher();
        Person teacher1 = new Teacher();

        System.out.println(teacher.name); //teacher
        teacher.hello(); //hello teacher
    
        System.out.println(teacher1.name);// person
        teacher1.hello(); // hello teacher
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

Scala

class Person {
    val name: String = "person"

    def hello(): Unit = {
        println("hello person")
    }
}

class Teacher extends Person {

    override val name: String = "teacher"

    override def hello(): Unit = {
        println("hello teacher")
    }
}

object Test {
    def main(args: Array[String]): Unit = {
        val teacher: Teacher = new Teacher()
        println(teacher.name) // teacher
        teacher.hello() // hello teacher

        val teacher1:Person = new Teacher
        println(teacher1.name) // teacher
        teacher1.hello() // hello teacher
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# 匿名子类

编辑 (opens new window)
上次更新: 2023/12/06, 01:31:48
函数式编程
Spark

← 函数式编程 Spark→

最近更新
01
k8s
06-06
02
进程与线程
03-04
03
计算机操作系统概述
02-26
更多文章>
Theme by Vdoing | Copyright © 2022-2025 Iekr | Blog
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式