Spark学习笔记11面向对象编程
面向对象编程
11.1 object类
11.1.1定义一个简单的类
11.1.2 field的getter与setter
定义类包含,定义类的field及方法。其格式如下
class ClassName{ // 其中类名首字母要大写
private var name = "Hys" // private修试符说明此变量只对本类有效
def sayHello(){ print("Hello," + name)
def getName = name // 获取name 的值
}
创建类的对象,并调用其方法
val field_name = new ClassName // 创建类对象
field_name.sayHello() // 调用类方法
print(field_name.getName()) // 调用类成员
11.1.3 构造函数-constructor
11.1.4 内部类
11.2 对象
11.3 继承
继承的主要有点:可以减少代码量
11.3.1 关键字extends
*父类中用final修饰的field和method是无法被子类继承的
示例代码:
class Person {
private var name = "George"
def getName = name
}
class Student extends Person {
private var score = "A"
def getScore = score
}
11.3.2 子类覆盖父类field和method
1.override关键字
使用此关键字覆盖可以帮助发现代码里的错误
2.父类方法被覆盖之后还可以使用super调用父类方法
示例代码:
class Person{
private var name = "George"
def getName = name
}
class teacher extends Person{
private var age = 20
def getAge = age
override def getName = "Hello " + super.getName
}
3. override field
示例代码:
class Person{
val name:String = "Hys"
def age:Int = 20
}
class Teacher extends Person{
override val name:String = "George"
override val age:Int = 30
}
4.isInstanceOf 和 asInstanceOf
isInstanceOf :判断指定对象是否为指定类或其子类的对象,如果对象是null则一定返回false
asInstanceOf:将指定对象转换为指定类型
示例代码:
class Person
class Teacher extends Person
val p:Person = new Teacher
val t:Teacher = null
if(p.isInstanceOf[Teacher]) t = p.asInstanceOf[Teacher]
5.getClass 和 classOf[类]
p.getClass 可以获取对象被实例化的类型
classOf[类] 可以获取精确的类
示例代码:
p.getClass == classOf[Person] 判断p是否是被实例化为Person类型
p.getClass == classOf[Teacher]
6. 模式匹配进行类型判断
*判断对象是否和该类及其子类的对象
p match{
case per:Person => println("it's Person's object")
case _ => println("Unknown type")
}
7.关键字protected
*父类中使用protected 修试的field 和 method在子类中直接就可以访问。
*当使用protected[this]时只能在"子类 当前对象"中访问父类的,其它对象不可以,包括同类对象。
代码示例:
class Person{
protected var name:String = "Hys"
}
class Teacher extends Person{
def sayHello() = {println("Hello " + name)}
}
val t = new Teacher
t.sayHello
8. 调用父类的构造函数constructor
*只能在子类的主constructor中调用父类的constructor;原因是辅构造函数只能调用本类的主构造函数或者辅构造函数
* 父类中接收的参数,子类中就不要用任何val 或者var 来修饰,否在认为是要覆盖父类的field
示例代码:
class Person(val name:String, val age:Int)
class Teacher(name:String, age:Int, var score:Double) extends Person(name,age){
def this(name:String){
this(name,0,0)
}
def this(age:Int){
this("Hys",age,0)
}
}
8.调用父类的constructor
* 每个类的辅助构造函数(constructor)只能调用本类的辅助constructor或者主constructor,所以要调用父类构造函数必须使用子类的主构造函数。
*如果是父类中接收的参数,子类接收时就不要用var或者val 来修饰了,否则会认位是覆盖父类的field 。
示例代码:
Class Person(val name:String, val age:Int){
Println("Person's name is " + name)
Println("Person's age is " + age)
}
Class Teacher(name:String, age:Int, var score:Double) extends Person(name, age){
def this(name:String){
this(name:String)
}
def this(age:Int){
this("Hys ",age,0)
}
Println(name + " " + age + " " + score)
}
val t = new Teacher("George", 20, 100)
Person's name is George
Person's age is 20
George 20 100.0
9.匿名内部类
*匿名子类:定义的没有名字的子类,同时直接创建其对象,然后将对象的引用赋予一个变量。然后匿名子类的对象也可以传给其它函数。
示例代码:
class Person(protected val name:String){
def sayHello = "Hello, I'm " + name
}
val p = new Person("Hys") {
override def sayHello = "Nice to meet you " + name} //匿名子类
def greeting(p:person{def sayHello:String}){ //把匿名子类当成参数传给函数
println(p.sayHello)
}
greeting(p) //调用匿名子类实例
10.抽象类
*抽象方法:定义时只有方法名和方法类型的方法。
*抽象类:包含抽象方法的类就是抽象类,即只要类中有一个抽象方法此类就为抽象类。
*抽象类必须用abstract关键词修饰。
*抽象类不可以被实例化。
*在子类中覆盖抽象类的方法时不需要用override关键字。
代码示例:
abstract class Person(){ //定义抽象类
def sayHello:String
}
class Teacher(name:String) extends Person{ //继承抽象类
def sayHello:String = {println("Hello" + name ); name} // 覆盖父类方法
}
val t = new Teacher("Hys")
t.sayHello
11.抽象field
*抽象field:定义field时只给出类型没有给出初值,这样的field就是抽象field。
*Scala会根据自己的规则为var或者val类型的field生成对应的getter和setter方法,但是父类中是没有field的,就父类中的抽象field不占内存。
*子类必须覆盖父类的抽象field。
*子类覆盖父类的抽象field不需要override关键字。
示例代码(子类不覆盖父类抽象field报错):
Abstract class Person{ //定义抽象类
Val name:String
}
class Teacher extends Person{} //子类不重写代码,报错
(子类正常继承父类)
class Teacher extends Person{
val name:String = "Hys" // 覆盖父类抽象方法
}
(子类把父类的抽象field继承为抽象field操作)
class Teacher extends Person{ val name:String } // 把父类抽象方法继承为抽象方法,如果不用abstract修饰子类会有报错
abstract class Teacher extends Person{ val name:String} //正确的把父类抽象方法继承为抽象方法
11.4 Trait
11.4.1基础知识
1.将trait作为接口使用
*类使用关键字extends继承
*与Java中的接口一样
*抽象方法不需要overrid管家你
*Scala不支持对类进行多继承,但可以多继承trait,使用with关键字
代码示例:
trait HelloTrait{
def sayHello(name:String)
}
trait MakeFriendsTrait{
def makeFriends(p:Person)
}
class Person(val name:String) extends HelloTrait with MakeFriendsTrait with Cloneable with Serializable{
def sayHello(name:String) = println("Hello " + name)
def makeFriends(p:Person) = println("Hello, my name is " + name + " your name is " + p.name)
}
2.在trait中定义具体方法
*就像类中定义方法一样
*不同之处在子类中调用是直接使用方法名就可以
trait computer{
def playVideo()={println("Play video")}
}
class Person extends computer{
playVideo()
def play()={playVideo()}
}
val p = new Person
p.playVideo
3.在trait中定义具体字段
*与类继承不同,trait定义的具体字段直接添加到了继承它的类中
trait Person{
val eyeNum:Int = 2
}
class Teacher(val name:String, val age:Int) extends Person{
println("Hello "+ name + ", you have " + eysNum + "eyes")
}
4.在trait中定义抽象字段
*trait中可以定义抽象字段,同时trait中的具体方法可以基于抽象字段来写,只不过继承trait的类必须覆盖抽象的field,提供具体的值
trait SayHello {
val name:String
def sayHello()={"Hello " + name}
}
class Person extends SayHello{
val name:String = "Hys" //覆盖trait中抽象字段
def makeFriends(p:Person){
sayHello()
println(name + ", nice to meet you")
}
}
11.4.2高级知识
1.为实例对象混入trait
*只有本对象可以调用
trait Loger{
def log(msg:String){print("loger trait")}
def logTrait(){println("loger trait")}
}
trait MyLoger extends Loger{
override def log(msg:String){println("log:" + msg)}
}
class Person(val name:String) extends Loger{
def sayHello{println("Hi,I'm " + name );log("sayHello is invoked!")}
}
val p2 = new Person("George") with MyLoger //动态混入trait
val p1 = new Person("Hys")
scala> p2.logTrait()
trait
scala> p1.log("")
loger trait
2.trait调用链
*继承同一个trait的多个trait,在具有相同method的最后都执行super.method,就可以从右向左依次执行每个被继承的多个trait中相同的方法,从而实现调用链。
代码示例:
trait Loger{
def vs(){}
def kk(){}
}
trait PersonReady extends Loger{
override def vs(){
println("I am ready")
super.vs() //执行此方法
}
}
trait PersonGo extends Loger{
override def vs(){
println("Please go!")
super.vs()
}
}
trait PersonEnd extends Loger{
override def vs(){
println("To be end!")
super.vs()
}
}
class PersonVs extends PersonEnd with PersonGo with PersonReady{
def aURD(name:String){
println("Are you ready")
vs() //执行调用链
}
}
3.在trait中覆盖抽象方法
*当子trait调用super.method_name 时要要给子trait的方法加上abstract override修饰
示例代码1(无super.method_name调用):
trait Logger{
def log(msg:String)
}
trait Mylogger extends Logger{
override def log(msg:String){}
}
示例代码2(有super.method_name调用):
trait Logger{
def log(msg:String)
}
trait Mylogger extends Logger{
abstract override def log(msg:String){super.log("kk")} // 当调用super.method_name时要用abstract修饰
}
4.混合使用trait的具体方法和抽象方法
*可以让trait中具体方法依赖于抽象方法,而抽象方法则放到继承trait的类中去实现,就好像是一个模板
trait Valid{
def getName:String //在trait中定义抽象方法
def valid:Boolean={ //在trait中定义具体方法
getName == "Hys"
}
}
class Person(val name:String) extends Valid{
println(valid) //此语句需要执行的函数及次序是construceto->getName->vaild
def getName = {println("Get the name.")
name
}
}
5.trait的构造机制
*trait中不包含在任何方法中的代码就是trait的构造代码
*构造代码执行优先级 父类构造函数->多个trait从左到右依次执行->父trait的构造代码->子类的构造函数
示例代码:
class Person{print("Person's constructor")}
trait Logger{println("\n Logger constructor")}
trait Logger{println("\n Logger constructor")}
trait TimeLogger extends Logger{println("TimeLogger")}
class Teacher extends Person with TimeLogger with MyLogger{println("Tescher class")}
实例化演示:
scala> val t = new Teacher
Person's constructor
Logger constructor
TimeLogger
Mylogger constructor
Tescher class
6.trait字段的初始化
*trait不可以接收带参数的构造函数,如果想使用trait初始化field,可以使用Scala的提前定义特性
示例代码:
trait SayHello{
val msg:String //需要初始化的字段
println(msg.toString) // 对初始化字段的调用
}
class Person
val p = new Person with SayHello //报错
val p = new {val msg:String = "Hys" //提前定义
} Person with SayHello
或者
class Person extends { val msg:String = "Hys" //提前定义
} with SayHello
还有办法就是使用lazy value
*如果不用lazy仍然会报异常
trait SayHello {
lazy val msg:String = null
println(msg:toString)
}
class Person extends SayHello //继承的时候没有用lazy,实例化时有异常发生
val p = new Person //有异常跳出
class Person extends SayHello{ override lazy val msg:String = "George"} //使用lazy覆盖该field,实例化时正常
val p = new Person
7.让trait继承类
*trait也可以继承自class,此时class就回成为所有继承该trait的类的父类
示例代码:
class Hys { println("class Hys")}
trait George extends Hys {println("trait George")} //trait 继承类
class Person extends George{println("class Person")} //之类继承继承了类的trait,此时trait继承的类相当于继承了该trait的父类。
scala> val p = new Person
class Hys
trait George
class Person
由构造函数执行内容和顺序可知Hys类是Person的父类
Spark学习笔记11面向对象编程的更多相关文章
- javascript 学习笔记之面向对象编程(一):类的实现
~~想是一回事,做是一回事,写出来又是一回事~~一直以来,从事C++更多的是VC++多一些,从面向过程到面向对象的转变,让我对OO的编程思想有些偏爱,将一个客观存在的规律抽象出来总是让人比较兴奋,通过 ...
- JavaSE学习笔记05面向对象编程01
面向对象编程01 java的核心思想就是OOP 面向过程&面向对象 面向过程思想: 步骤清晰简单,第一步做什么,第二步做什么...... 面向过程适合处理一些较为简单的问题 面向对象思想: 物 ...
- python 学习笔记7 面向对象编程
一.概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发"更快更好更强..." ...
- C++ Primer 学习笔记_67_面向对象编程 --转换与继承、复制控制与继承
面向对象编程 --转换与继承.复制控制与继承 I.转换与继承 引言: 由于每一个派生类对象都包括一个基类部分,因此能够像使用基类对象一样在派生类对象上执行操作. 对于指针/引用,能够将派生类对象的指针 ...
- javascript 学习笔记之面向对象编程(二):继承&多态
~~接上篇~~上一篇实现了类的实现以及类成员变量和方法的定义,下面我们来了解下面向对象中两个最重要的特性:继承和多态. 继承 js中同样可以实现类的继承这一面向对象特性,继承父类中的所有成员(变量和属 ...
- C++ Primer 学习笔记_69_面向对象编程 --继承情况下的类作用域
面向对象编程 --继承情况下的类作用域 引言: 在继承情况下,派生类的作用域嵌套在基类作用域中:假设不能在派生类作用域中确定名字,就在外围基类作用域中查找该名字的定义. 正是这样的类作用域的层次嵌套使 ...
- C++ Primer 学习笔记_72_面向对象编程 --句柄类与继承[续]
面向对象编程 --句柄类与继承[续] 三.句柄的使用 使用Sales_item对象能够更easy地编写书店应用程序.代码将不必管理Item_base对象的指针,但仍然能够获得通过Sales_item对 ...
- python学习笔记(七):面向对象编程、类
一.面向对象编程 面向对象--Object Oriented Programming,简称oop,是一种程序设计思想.在说面向对象之前,先说一下什么是编程范式,编程范式你按照什么方式来去编程,去实现一 ...
- python自动化测试学习笔记-7面向对象编程,类,继承,实例变量,邮件
面向对象编程(OOP)术语: class TestClass(object): val1 = 100 def __init__(self): self.val2 = 200 ...
随机推荐
- JS函数可以再添加属性(包括方法)
1 前言 JS函数可以再添加属性(包括方法),这个有点有趣,记录一下. 2 代码 <!DOCTYPE html> <html> <head> <title&g ...
- Penettation testing with the bush Shell
1. Network Reconnaissance first we can use the command to gather the site information by whois eg : ...
- 编译linux内核前用make menuconfig设置时 Unable to find the ncurses ibraries的解决办法
今天在更新CentOS或者Ubuntu的内核时,执行make menuconfig可能看如这样的错误: *** Unable to find the ncurses libraries or the ...
- JS 的骚操作
一.强制类型转换 1.1string强制转换为数字 //可以用*1来转化为数字((实际上是调用.valueOf方法) 然后使用Number.isNaN来判断是否为NaN,或者使用 a !== a 来判 ...
- 大数据项目之_15_帮助文档_NTP 配置时间服务器+Linux 集群服务群起脚本+CentOS6.8 升级到 python 到 2.7
一.NTP 配置时间服务器1.1.检查当前系统时区1.2.同步时间1.3.检查软件包1.4.修改 ntp 配置文件1.5.重启 ntp 服务1.6.设置定时同步任务二.Linux 集群服务群起脚本2. ...
- VB开发类似IIS简易的WebServer,代码不到100行
最近遇到三个人问关于VB写网页服务器的问题,所以今天抽时间写一下,演示其实没有多复杂. 代码里自定义的方法只有四个,没有公共变量绕来绕去,该注释的也都注释了. 想扩展更复杂的功能,就需要自己补脑HTT ...
- ZAB协议与Paxos算法
ZooKeeper并没有直接采用Paxos算法,而是采用一种被称为ZAB(ZooKeeper Atomic Broadcast)的一致性协议 ZooKeeper是一个典型的分布式数据一致性的解决方案, ...
- 两个排序链表的合并(Easy)
问题来源:选自leetcode 21:合并两个有序链表 问题描述: 题目给定信息: 给定两个有序链表,把两个链表合并成一个链表,并且合并后的链表依然是有序的.这两个链表中允许有重复元素 问题分析: 设 ...
- Javascript Date类型
Date 类型使用自 UTC 1970 年 1 月 1日 午夜 开始经过的毫秒数来保存日期. 创建日期对象 var now = new Date();//获取当前日期 Date.parse ...
- Python练手例子(7)
37.对10个数进行排序. 程序分析:可以利用选择法,即从后9个比较过程中,选择一个最小的与第一个元素交换,下次类推,即用第二个元素与后8个进行比较,并进行交换. #python 3.7 if __n ...