Scala的学习(四)面向对象
目录
一、对象创建流程
二、包的可见性
三、构造器
四、面向对象三大特性
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、当属性访问权限为默认时,从底层看属性是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的
案例
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. 当调用对象属性时,没有动态绑定机制,哪里声明,那里使用
2)val只能重写另一个val 属性 或 重写不带参数的def
3)var只能重写另一个抽象的var属性
抽象属性:声明未初始化的变量就是抽象的属性,抽象属性在抽象类
8) 抽象类
abstract class Person() { // 抽象类
var name: String // 抽象字段, 没有初始化
def printName // 抽象方法, 没有方法体
}
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 接口名1,接口2
1)在Java中, 一个类可以实现多个接口。
2)在Java中,接口之间支持多继承
3)接口中属性都是常量
4)接口中的方法都是抽象的
从面向对象来看,接口并不属于面向对象的范畴,Scala是纯面向对象的语言,在Scala中,没有接口。
Scala语言中,采用特质trait(特征)来代替接口的概念,也就是说,多个类具有相同的特征(特征)时,就可以将这个特质(特征)独立出来,采用关键字trait声明。 理解trait 等价于(interface + abstract class)
2)Scala中trait 的使用
一个类具有某种特质(特征),就意味着这个类满足了这个特质(特征)的所有要素,所以在使用时,也采用了extends关键字,如果有多个特质或存在父类,那么需要采用with关键字连接
3)特质的快速入门案例
可以把特质可以看作是对继承的一种补充Scala引入trait特征 第一可以替代Java的接口, 第二个也是对单继承机制
的一种补充。
Scala提供了特质(trait),特质可以同时拥有抽象方法和具体方法,一个类可以实现/继承多个特质
说明:和Java中的接口不太一样的是特质中的方法并不一定是抽象的,也可以有非抽象方法
Scala的学习(四)面向对象相关推荐
- 第四课 尚硅谷Scala语言学习-面向对象
第四课 尚硅谷Scala语言学习-面向对象 文章目录 第四课 尚硅谷Scala语言学习-面向对象 第一节 Scala 包 1.1 包基本语法 1.2 包说明 1.3 包对象 1.4 导包说明 第二节 ...
- 十四、理解nn.module方法——学习python面向对象编程(一)
起因 在(十二)中说到pytorch中创建神经网络的两种方法:一个是Sequential类(这也是一种继承父类属性和方法并可对其方法重构的子类),另一个是自己编写代码,继承nn.module类,对其内 ...
- 大数据学习,Scala快速学习的方法
大数据学习过程中,都会学习Scala,众所周知,Spark支持4门语言,分别为R.Python.Java与Scala,但真正的底层实现语言则是Scala.在我以往的实践分享中,除了Python,我还会 ...
- Scala进阶之路-面向对象编程之类的成员详解
Scala进阶之路-面向对象编程之类的成员详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Scala中的object对象及apply方法 1>.scala 单例对象 ...
- java学习四个月以来的想法
java学习四个月以来的想法 从五月开始接触编程到现在差不多四个月了,其实我在2018年的时候就听别人介绍过编程,因为我自己学得是工科类专业,掌握一门编程语言对自己以后有好处,所以才在今年开始学习 ...
- 深圳Java学习:面向对象【重点知识】
深圳Java学习:面向对象[重点知识] 在Java的学习中,面向对象应该是Java技术的重中之重,虽然在生活中没有对象可以面对,但在技术中还是要一直接触面对对象,而且不可避免.今天千锋小编对面向对象来 ...
- C#多线程学习(四) 多线程的自动管理(线程池) (转载系列)——继续搜索引擎研究...
在多线程的程序中,经常会出现两种情况: 一种情况: 应用程序中,线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应 这一般使用ThreadPo ...
- Scala 递归学习的例子
Scala 递归学习的例子 为了学习Spark,我开始了学习Scala.加油! 递归的一个题目: 代码: // Why x is Float, but when we use 3.0 for exam ...
- Python学习之面向对象编程
Python学习目录 在Mac下使用Python3 Python学习之数据类型 Python学习之函数 Python学习之高级特性 Python学习之函数式编程 Python学习之模块 Python学 ...
最新文章
- 统计所有子串写到文件
- Android VNC Server
- 合并的表格怎么加横线_excel表格如何在数据之间加横线-在excel里怎么添加单元格横线...
- mysql之ALTER COLUMN、CHANGE COLUMN、MODIFY COLUMN的区别
- 【小白学PyTorch】13.EfficientNet详解及PyTorch实现
- 云服务器Linux jdk安装详解(centos8)
- jenkins角色权限管理
- mysql数据库显示问号_mysql数据库中文显示问号
- Nignx出现failed (3: The system cannot find the path specified)问题
- 内推|商汤科技深度学习方向实习生
- mybatis 插入数据时返回主键
- 干货 | 万字长文带你复习线性代数!
- Android Cursor浅析
- windirstat怎么用_使用WinDirStat分析和管理硬盘空间
- 安卓手机root推荐,导出安卓分区镜像
- 合并两个有序链表-c语言
- 静态HTML+CSS 中国高等教育学生信息网(学信网)网站
- Get IT技能百科库 50个领域轻松直达
- vue element 确认弹框中显示图片(message里)
- Java 身份证验证(IdCardVerification)