目录

一、对象创建流程

二、包的可见性

三、构造器

四、面向对象三大特性

1、封装

案例

2、继承

1)Scala继承的基本语法

2)Scala继承快速入门

3)scala子类继承了什么,怎么继承了?

4)重写方法

5)Scala中类型检查和转换

6)Scala中超类的构造

7)覆写字段

8) 抽象类

9)匿名子类

3、多态

五、伴生对象

1、伴生对象的快速入门

伴生类

2、伴生对象的小结

3、伴生对象-apply方法

六、Scala中trait的介绍

1)回顾Java接口

2)Scala中trait 的使用

3)特质的快速入门案例


一、对象创建流程

看一个案例

class Person {
  var age: Short = 90
  var name: String = _
  def this(n: String, a: Int) {
    this()
    this.name = n
    this.age = a
  }}

var p : Person = new Person("小倩",20)

流程分析(面试题-写出)

1)加载类的信息(属性信息,方法信息)
2)在内存中(堆)开辟空间
3)使用父类的构造器(主和辅助)进行初始
4)使用主构造器对属性进行初始化 【age:90, naem nul】
5)使用辅助构造器对属性进行初始化 【 age:20, naem 小倩 】
6)将开辟的对象的地址赋给 p这个引用)
(扩展)在Scala中创建对象共有几种方式?
1.new 对象
2.apply 创建
3.匿名子类方式
4.动态混入

二、包的可见性

1、当属性访问权限为默认时,从底层看属性是private的,但是因为提供了xxx_$eq()[类似setter]/xxx()[类似getter] 方法,因此从使用效果看是任何地方都可以访问)

2、当方法访问权限为默认时,认为public访问权

3、private为私有权限,只在类的内部伴生对象中可用 【案例演示】

4、protected为受保护权限,scala中受保护权限比Java中更严格,只能子类访问,同包无法访问 (编译器)

在scala中没有public关键字,即不能用public显式的修饰属性和方法

5、包访问权限(表示属性有了限制。同时包也有了限制),这点和Java不一样,体现出Scala包使用的灵活性。[案

三、构造器

构造器(constructor)又叫构造方法,是类的一种特殊的方法,它的主要作用是完成对新对象的初始化

Scala类的构造器包括: 构造助构造

主构造器会执行类定义中的所有语,这里可以体会到Scala的函数式编程和面向对象编程融合在一起,即:构造器也是方法(函数)

助构造器名称为this(这个和Java是不一样的),多个辅助构造器通过不同参数列表进行区分, 在底层就是构造器重载。案例演示+反编译

object Demo1  {class Person{var name:String=_var age:Int =_def this(name:String){//辅助构造器无论是直接或间接,最终都一定要调用主构造器,执行主构造器的逻辑//而且需要放在辅助构造器的第一行// [这点和java一样,java中一个构造器要调用同类的其它构造器,也需要放在第一行]this();//直接调用主构造器this.name=name;}def this(name:String,age:Int){this();this.name=name;this.age=age;}def this(age:Int){this("匿名")//间接调用了主构造器,因为def this(name:String)中调用了主构造器this.age=age}def showInfo():Unit={println("Person信息如下:")println("name="+this.name)println("age="+this.age)}}def main(args: Array[String]): Unit = {val p1 = new Person("scott")val p2 = new Person(18)val p3 = new Person("scott",12)p1.showInfo()p2.showInfo()p3.showInfo()}}

四、面向对象三大特性

1、封装

         1)Scala中为了简化代码的开发,当声明属性时,本身就自动提供了对应setter/getter方法,如果属性声明为private的,那么自动生成的setter/getter方法也是private的,如果属性省略访问权限修饰符,那么自动生成的setter/getter方法是public的

2)因此我们如果只是对一个属性进行简单的setget ,只要声明一下该属性(属性使用默认访问修饰符) 不用写专门的getset,默认会创建,访问时,直接对象.变量。这样也是为了保持访问一致性
3)从形式上看 dog.food 直接访问属性,其实底层仍然是访问的方法,  看一下反编译的代码就明白
4)有了上面的特性,目前很多新的框架,在进行反射时,也支持对属性的直接反射

案例

object Demo2 {class Person{var name:String=_//var age;//当是public时可随意修改不安全private var age:Int=_private var salary:Float=_private var job:String=_def setAge(age:Int): Unit ={if (age>=0&&age<=120){this.age=age}else{println("输入的数据不合理")//给个默认值this.age=20;}}def getAge: Int ={this.age//或return age}}def main(args: Array[String]): Unit = {var p1 = new Person()// p1.setAge(150)//输入的数据不合理p1.setAge(10)println(p1.getAge)//10}
}

2、继承

1)Scala继承的基本语法

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

2)Scala继承快速入门

object Demo3 {class Man{var name:String=_var age:Int=_def showInfo(): Unit ={println("信息如下")println("姓名:"+this.name)}}class Student extends Man{def studing(): Unit ={println(this.name+"学习 scala 中......")}}def main(args: Array[String]): Unit = {val s1 = new Student()s1.name="张无忌"s1.showInfo()s1.studing()}
}

3)scala类继承了什么,怎么继承了?

子类继承了所有的属性,只是私有的属性不能直接访问,
需要通过公共的方法去访问

4)重写方法

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

override def showInfo(): Unit = {println("学生信息 姓名"+this.name) super.showInfo()
}

5)Scala中类型检查和转换

要测试某个对象是否属于某个给定的类,可以用isInstanceOf方法。用asInstanceOf方法将引用转换为子类的引用。classOf获取对象的类名。

classOf[String]就如同Java的 String.class 。

obj.isInstanceOf[T]就如同Java的obj instanceof T 判断obj是不是T类型

obj.asInstanceOf[T]就如同Java的(T)obj obj强转成T类型

//获取对象的类型
println(classOf[String])//class java.lang.String
val s = "zhaosi"
//用反射的方式得到对象的类型
println(s.getClass.getName)//java.lang.String
//判断s是不是String类型
println(s.isInstanceOf[String])//true
//将s显示转换成String
println(s.asInstanceOf[String])//zhaosi
var man = new Man
var stu = new Student
man = stu //将子类对象赋给父类
man.name="无名"
println(stu.name)//无名
man.asInstanceOf[Student].studing()//无名学习 scala 中......

类型检查和转换的最大价值在于:可以判断传入对象的类型,然后转成对应的子类对象,进行相关操作,这里也体现出多态的特点。

6)Scala中超类的构

  • 类有一个主构器和任意数量的辅助构造器,而每个辅助构造器都必须先调用主构造器(也可以是间接调用.)

  • 只有主构造器可以调的构造器。辅助构造器不能直接调用父类的构造器。在Scala的构造器中,你不能调用super(params)

class Person(name: String) { //父类的构造器

}

class Emp (name: String) extends Person(name) {// 将子类参数传递给父类构造器,这种写法

// super(name)  (×) 没有这种语

   def  this() {

     super("abc") // (×)不能在辅助构造器中调用父类的构造器

   }

}

实例

object Demo4 {class Person(pname:String){var name:String =pnamedef printname() ={println("1 my name "+name)}}class Student(studentname: String) extends Person(studentname){var sno:Int = 20override def printname(): Unit = {super.printname()println("2 my name"+name)}}def main(args: Array[String]): Unit = {val ss = new Student("张三")ss.printname()}
}


7)覆写字段

在Scala中,子类改写父类的字段,我们称为覆写/重写字段。覆写字段需使用 override修饰。

回顾:在Java中只有方法的重写,没有属性/字段的重写,准确的讲,是隐藏字段代替了重写

回顾-Java另一重要特性: 动态绑定机制

1. 当调用对象方法的时候,该方法会和该对象的内存地址绑定

2. 当调用对象属性时,没有动态绑定机制,哪里声明,那里使用


写字段的注意事项和细节
1)def只能重写另一个def(即:方法只能重写另一个方法)

2)val只能重写另一个val 属性 或 重写不带参数的def

3)var只能重写另一个抽象的var属性

象属性:声明未初始化的变量就是抽象的属性,抽象属性在抽象类


   var重写抽象的var属性小结
1.个属性没有初始化,那么这个属性就是抽象属
2.抽象属性在编译成字节码文件时,属性并不会声明,但是会自动生成抽象方法,所以类必须声明为抽象
3.如果是覆写一个父类的抽象属性,那么override 关键字可省 [原因:父类的抽象属性,生成的是抽象方法,因此就不涉及到方法重写的概念,因此override可省略]

8) 抽象类

abstract class Person() { // 抽象类

var name: String // 抽象字段, 没有初始化

def printName // 抽象方法, 没有方法体

}

Scala象类使用的注意事项和细节讨
1)抽象类不能被实例
2)抽象类不一定要包含abstract方法。也就是说,抽象类可以没有abstract方法
3)一旦类包含了抽象方法或者抽象属性,则这个类必须声明为abstract
4)抽象方法不能有主体,不允许使用abstract修饰。
5)如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法和抽象属性,除非它自己也声明为abstract类。
6)抽象方法和抽象属性不能使用private、final 来修饰,因为这些关键字都是和/实现相违背的。
7)抽象类中可以有实现的方法.
8)子类重写抽象方法不需要override,写上也不会错.

9)匿名子类

object Demo5 {abstract class Animal{var name:Stringdef shout()}def main(args: Array[String]): Unit = {var animal = new Animal {override var name: String = "青蛙"override def shout(): Unit = {println(name+"呱呱叫")}}animal.shout()//青蛙呱呱叫}
}

3、多态

动态绑定,重写方法,覆盖字段,重载

五、伴生对象

回顾下Java的静态概念
public static 返回值类型  方法名(参数列表) {方法体}

静态属性...

说明: Java中静态方法并不是通过对象调用的,而是通过类对象调用的,所以静态操作并不是面向对象的。


Scala中静态的概念-伴生对象
Scala语言是完全面向对象(万物皆对象)的语言,所以并没有静态的操作(即在Scala中没有静态的概念)。但是为了能够和Java语言交互(因为Java中有静态概念),就产生了一种特殊的对象来模拟类对象,我们称之为类的伴生对象。这个类的所有静态内容都可以放置在它的伴生对象中声明和调用。


1、伴生对象的速入门

伴生类

class ScalaPerson {

var name : String = _

}

伴生对象

object ScalaPerson {

var sex : Boolean = true

}

2、伴生对象的小结

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.方法 来实现调用

3、伴生对象-apply方法

在伴生对象中定义apply方法,可以实现: 类名(参数) 方式来创建对象实例.

object Demo6 {//创建一个伴生类class Bird(bname:String){var name:String = bname}//创建一个伴生对象object Bird{def apply(bname: String): Bird ={println("有参apply被调用了")new Bird(bname)}def apply(): Bird = {println("无参apply被调用了")new Bird("lala")}}def main(args: Array[String]): Unit = {Bird("喜鹊")//有参apply被调用了Bird()//无参apply被调用了}
}

六、Scala中trait的介绍

1)回顾Java接口

声明接口

interface 接口名

实现接口

class implements 接口12

1)在Java中, 一个类可以实现多个接口。

2)在Java中,接口之间支持多继承

3)接口中属性都是常量

4)接口中的方法都是抽象的

从面向对象来看,接口并不属于面向对象的范畴,Scala是纯面向对象的语言,在Scala中,没有接口。

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

2)Scalatrait 使用

一个类具有某种特质(特征),就意味着这个类满足了这个特质(特征)的所有要素,所以在使用时,也采用了extends关键字,如果有多个特质或存在父类,那么需要采用with关键字连接

3)特质的快速入门案例

以把特质以看作是对继承的一种补充Scala引入trait特征 第一可以替代Java的接口,  第二个也是对单继承

一种补充。

Scala提供了特质(trait),特质可以同时拥有抽象方法和具体方法,一个类可以实现/继承多个特质

说明:和Java中的接口不太一样的是特质中的方法并不一定是抽象的,也可以有非抽象方法

Scala的学习(四)面向对象相关推荐

  1. 第四课 尚硅谷Scala语言学习-面向对象

    第四课 尚硅谷Scala语言学习-面向对象 文章目录 第四课 尚硅谷Scala语言学习-面向对象 第一节 Scala 包 1.1 包基本语法 1.2 包说明 1.3 包对象 1.4 导包说明 第二节 ...

  2. 十四、理解nn.module方法——学习python面向对象编程(一)

    起因 在(十二)中说到pytorch中创建神经网络的两种方法:一个是Sequential类(这也是一种继承父类属性和方法并可对其方法重构的子类),另一个是自己编写代码,继承nn.module类,对其内 ...

  3. 大数据学习,Scala快速学习的方法

    大数据学习过程中,都会学习Scala,众所周知,Spark支持4门语言,分别为R.Python.Java与Scala,但真正的底层实现语言则是Scala.在我以往的实践分享中,除了Python,我还会 ...

  4. Scala进阶之路-面向对象编程之类的成员详解

    Scala进阶之路-面向对象编程之类的成员详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Scala中的object对象及apply方法 1>.scala 单例对象 ...

  5. java学习四个月以来的想法

    java学习四个月以来的想法 ​ 从五月开始接触编程到现在差不多四个月了,其实我在2018年的时候就听别人介绍过编程,因为我自己学得是工科类专业,掌握一门编程语言对自己以后有好处,所以才在今年开始学习 ...

  6. 深圳Java学习:面向对象【重点知识】

    深圳Java学习:面向对象[重点知识] 在Java的学习中,面向对象应该是Java技术的重中之重,虽然在生活中没有对象可以面对,但在技术中还是要一直接触面对对象,而且不可避免.今天千锋小编对面向对象来 ...

  7. C#多线程学习(四) 多线程的自动管理(线程池) (转载系列)——继续搜索引擎研究...

    在多线程的程序中,经常会出现两种情况: 一种情况:   应用程序中,线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应                   这一般使用ThreadPo ...

  8. Scala 递归学习的例子

    Scala 递归学习的例子 为了学习Spark,我开始了学习Scala.加油! 递归的一个题目: 代码: // Why x is Float, but when we use 3.0 for exam ...

  9. Python学习之面向对象编程

    Python学习目录 在Mac下使用Python3 Python学习之数据类型 Python学习之函数 Python学习之高级特性 Python学习之函数式编程 Python学习之模块 Python学 ...

最新文章

  1. 统计所有子串写到文件
  2. Android VNC Server
  3. 合并的表格怎么加横线_excel表格如何在数据之间加横线-在excel里怎么添加单元格横线...
  4. mysql之ALTER COLUMN、CHANGE COLUMN、MODIFY COLUMN的区别
  5. 【小白学PyTorch】13.EfficientNet详解及PyTorch实现
  6. 云服务器Linux jdk安装详解(centos8)
  7. jenkins角色权限管理
  8. mysql数据库显示问号_mysql数据库中文显示问号
  9. Nignx出现failed (3: The system cannot find the path specified)问题
  10. 内推|商汤科技深度学习方向实习生
  11. mybatis 插入数据时返回主键
  12. 干货 | 万字长文带你复习线性代数!
  13. Android Cursor浅析
  14. windirstat怎么用_使用WinDirStat分析和管理硬盘空间
  15. 安卓手机root推荐,导出安卓分区镜像
  16. 合并两个有序链表-c语言
  17. 静态HTML+CSS 中国高等教育学生信息网(学信网)网站
  18. Get IT技能百科库 50个领域轻松直达
  19. vue element 确认弹框中显示图片(message里)
  20. Java 身份证验证(IdCardVerification)

热门文章

  1. 人工智能领域,符号计算、模式识别、专家系统和机器翻译的基本介绍
  2. Vue中watch选项handle、deep、immediate是什么
  3. 【技术】作为测试,你应该知道的MySQL知识(二)
  4. 【计算机体系结构】什么是流水线?
  5. php生成字母头像,php 按照中文字母名字排序,并把相应的头像显示出来
  6. 黑科技--- 电影日历/表情搜索/抖音网页版/去水印/网易云游戏平台
  7. 关于互联-这些你可能很想知道
  8. 25-爬取大众点评的评论【坑多】
  9. 二月开班通知丨黑马20校区火力全开,多班级爆满!
  10. keil 5支持 LPC1114FBD48/302,1