基本类的使用:(初)

 package com.dtspark.scala.basics
/**
* trait是一个接口
* 接口的第一次继承用extends,多继承时用with
* 多继承时,如果这些接口中都有同样的方法时,则是从右往左的顺序执行
* 抽象类不能实例化
* 类继承的时候不继承伴生对象object,只能看见类的接口,而其父类可以使用自己伴生对象中的方法
* isInstanceOf 和 asInstanceOf的使用
* 前者是判断是不是其子类,后者是进行类型转换,但必须是父子之间的转换,不能是完全不同的类
*/
trait Logger{
def log(message:String){
println("logger "+message)
} }
/**
* override 是表示重写原有方法,(必须要写)
*/
trait RichLogger extends Logger{
override def log(message:String){
println("RichLogger:"+message)
}
} class Loggin( name:String)extends Logger{
def loggin{
println("Hi,welcome! "+name)
log(name)
} } trait Information{ val information:String //抽象属性
//def getId:String
def getInformation:String //抽象方法(不存在方法体)
def checkIn:Boolean = {
getInformation.equals("Spark")
}
} class Passenger( name:String)extends Information{
//不可以定义为val 原因是因为_的值不明确
var id:String=_ //这种方法申明的不是抽象属性,而是可变属性,其值为String的默认值null
override val information = name //重写抽象属性
override def getInformation = information //不执行任何操作,直接给返回值,相当于实现了
/**
* this关键字为构造方法,重写构造方法
* 副构造函数的第一行必须是构造函数
*/
def this(name:String,iid:String){
this(name)
id=iid;
println("hello!!")
}
def out:String={
name+" : "+id
} } object HelloTrait {
def main(args: Array[String]): Unit = {
/**
* 对象实例化之后又继承了新的接口,可以使用新的方法
* 新的接口必须继承至原有的接口,并重写新的方法
*/
val Log = new Loggin("Spark")with RichLogger
Log.loggin val person = new Passenger("zcb")
println(person.out)
person.id="123" //不具有封装性
println(person.out)
val person1 = new Passenger("zcb1","1234")
println(person1.out)
val a:Boolean=person.isInstanceOf[Information]//看它是不是其子类
println(a)
}
}

类的继承和判断对象是否相等(中)

 package com.dtspark.scala.basics
/**
*class Creature {
* val range: Int = 10
* val env: Array[Int] = new Array[Int](range)
*} *class Ant extends Creature {
* override val range = 2
*}
* 在构造时,发生的过程如下:
* Ant构造器在构造自己之前,调用超类构造器;
* Creature的构造器将range字段设为10;
* Creature的构造器初始化env数组,调用range字段的getter;
* range的getter被Ant类重写了,返回的Ant类中的range,但是Ant类还未初始化,所以返回了0;
* env被设置成长度为0的数组
* Ant构造器继续执行,将range字段设为2
* -------------------------------------------------------------
* 第二种写法是先初始化sporter的成员,然后在初始化父类的成员,这样可保证将数据传给父类,with后面接要继承的类
* class Person10{
* val counter=3
* val counterArray =new Array[Int](counter)
* }
 
* class Sporter extends {
* override val counter = 5
* }with Person10 **/这样初始化后sporter的counterArray的长度为5
class Person10{
val counter=3
val counterArray =new Array[Int](counter)
} class Sporter extends {
override val counter = 5
}with Person10 //判断两个对象是否相同的方法
class Programmer(val name:String,val salary:Double){
final override def equals(other:Any)={
val that = other.asInstanceOf[Programmer]
if(that==null)false
else name == that.name&&salary==that.salary
}
/**
* 1.hashCode()方法存在的主要目的就是提高效率。
* 2.在集合中判断两个对象相等的条件,其实无论是往集合中存数据,
* 还是从集合中取数据,包括如果控制唯一性等,都是用这个条件判断的,条件如下:
* 首先判断两个对象的hashCode是否相等,如果不相等,就认为这两个对象不相等,就完成了。
* 如果相等,才会判断两个对象的equals()是否相等,如果不相等,就认为这两个对象不相等,
* 如果相等,那就认为这两个对象相等。 * 所以说重写equals时必须重写hashcode,这是良好的习惯
*/
final override def hashCode=name.hashCode()*5+salary.hashCode()*9 } //object OverrideField {
// def main(args: Array[String]): Unit = {
// val s = new Sporter
// println(s.counterArray.length)
// }
//}
//第二种写法,不用写main函数
object OverrideField extends App{
val s = new Sporter
println(s.counterArray.length)
}

注:对于无序表寻找是否有相同的对象时,使用hashcode可以大大提高速度。equal的比较通常比较耗资源,可以先比较hashcode后,确认hashcode相同时再用equal比较。

hashcode相同,equal不一定相同;equal相同的hashcode一定相同。

类的提取器:(中)

 package com.dtspark.scala.basics
/**
* 类的提取器
* 注解要搞懂下面两个
* @transient 注解将字段标记为瞬态的
* @volatile 注解标记为易失的
*
* 自己编写的注解要继承annotation.Annotation
*/
case class Person1(name:String ,age:Int) class DTCoder(val name:String ,val salary:Int)
object DTCoder{
//复写了其apply和unapply方法
def apply(name:String,salary:Int)={
println("DTCoder apply method invoked!!!")
new DTCoder(name,salary)
}
// 方法1 (可使一个字符串转换成一个对象)
// def unapply(information:String)={
// //根据空格区分参数
// println("DTCoder unapply method invoked!!!")
// Some((information.substring(0 , information.indexOf(" ")),information.substring(information.indexOf(" ")+1)))
// }
//方法二
def unapply(information:DTCoder)={
//根据空格区分参数
println("DTCoder unapply method invoked!!!")
Some((information.name,information.salary))
}
} object HelloExtractor {
def main(args: Array[String]): Unit = {
val person=Person1("Spark",12)//调用apply的工厂构造方法,构造出类的实例
//= val person =Person1.apply("Spark",12)
val Person1(name,age)=person//调用Person1的unapply的方法把person实例中的name和age提取出来
println(person.name+" : "+person.age)//实现了name和age的赋值。 person match{ //val Person1(name,age)=person=match这个过程
case Person1(name,age)=>println(name+" : "+age)
}
//针对unapply方法一
//val DTCoder(dtname,salary) = "Spark 16000000" //针对unapply方法二
val coder = DTCoder("Spark",2999999)
val DTCoder(dtname,salary)=coder
}
}

类的伴生对象:(高)

添加类的内容:

 class Marker ( color:String)
class Marker (val color:String)
class Marker (var color:String)
 

这两种申明是有差的,第二种和第三种申明都可以通过Marker的对象+"."直接调用(相当于这个属性是静态的),而第一种申明不行

 class Marker private (val color:String) {

   println("创建" + this)

   override def toString(): String = "颜色标记:"+ color

 }

private写在类名和参数中间表示对主构造函数的私有化,这时是不能new出对象的(除非有伴生对象object或者有重构this构造函数)

 def main(args: Array[String]) {
new Marker("black")//报错
}
第一种解决方案:
添加object后,同时要有apply方法,否则还是报错(伴生对象是不带参数的,但是apply方法需要与原类相同的参数)
由于有apply方法的存在,创建新对象时,不需要用new关键字,
用object初始化时,他会直接初始化object中存在的所有变量。
 object zcb01 {
def main(args: Array[String]) {
Marker("white") //直接对象名进行初始化
} }
class Marker (val color:String) { println("创建" + this) override def toString(): String = "颜色标记:"+ color } object Marker{ private val markers: Map[String, Marker] = Map(
"red" -> new Marker("red"),
"blue" -> new Marker("blue"),
"green" -> new Marker("green")
)
private val m = Set(new Marker("black"))
def apply(color:String) = {
if(markers.contains(color)) markers(color) else null
println("我输入的颜色:"+color)
} }

结果:(先将object中的元素初始化,然后再调用apply方法初始化当前对象)

创建颜色标记:red
创建颜色标记:blue
创建颜色标记:green
创建颜色标记:black
我输入的颜色:white

第二种解决方案:
重构构造器(创建对象时必须用new,因为object(apply方法)不支持除主构造以外的任何重载构造方式)
 object zcb01 {
def main(args: Array[String]) {
new Marker("white",4)
} }
class Marker private (val color:String) {//主构造的形式与类名后面的形式相同 println("创建" + this)
var a=1; def this(color:String,a:Int){
this(color)//必须先调用主构造器
this.a=a;
} override def toString(): String = "颜色标记:"+ color }

Scala学习——类,继承,接口(中)的更多相关文章

  1. Scala的类继承

    Scala的类继承 extend Scala扩展类的方式和java一样使用extends关键字 class Employee extends Person { } 与java一样,可以在定义的子类重写 ...

  2. Java:验证在类继承过程中equals()、 hashcode()、toString()方法的使用

    以下通过实际例子对类创建过程汇中常用的equals().hashcode().toString()方法进行展示,三个方法的创建过程具有通用性,在项目中可直接改写. //通过超类Employee和其子类 ...

  3. Kotlin学习快速入门(3)——类 继承 接口

    类 参考链接 类定义格式 使用class关键字定义,格式如下: class T{ //属性 //构造函数 //函数 //内部类 } Java Bean类 java bean类 //java bean类 ...

  4. Scala学习八——继承

    一.本章要点 extends,final关键字和Java一样 重写方法时必须使用override 只有主构造器可以调用超类的构造器 可以重写字段 二.扩展类 Scala扩展类和Java一样(使用ext ...

  5. scala学习-类与对象

    类 / 对象 [<快学Scala>笔记] 一.类 1.Scala中的类是公有可见性的,且多个类可以包含在同一个源文件中: class Counter{ private var value ...

  6. Java类继承关系中的初始化顺序

    Java类初始化的顺序经常让人犯迷糊,现在本文尝试着从JVM的角度,对Java非继承和继承关系中类的初始化顺序进行试验,尝试给出JVM角度的解释. 非继承关系中的初始化顺序 对于非继承关系,主类Ini ...

  7. 【深入理解JVM】:Java类继承关系中的初始化顺序

    尝试着仔细阅读thinking in java 看到一篇很好的文章http://blog.csdn.net/u011080472/article/details/51330114

  8. Programming In Scala笔记-第十一章、Scala中的类继承关系

    本章主要从整体层面了解Scala中的类层级关系. 一.Scala的类层级 在Java中Object类是所有类的最终父类,其他所有类都直接或间接的继承了Object类.在Scala中所有类的最终父类为A ...

  9. iOS学习——iOS 整体框架及类继承框架图

    整理自:IOS 整体框架类图值得收藏 一 整体框架 在iOS开发过程中,对iOS的整理框架的了解和学习是必不可少的一个环节,今天我们就好好来了解一下iOS的整体框架.首先贴一个关于iOS的框架介绍:i ...

随机推荐

  1. git是一种分布式代码管理工具,git通过树的形式记录文件的更改历史,比如: base'<--base<--A<--A' ^ | --- B<--B' 小米工程师常常需要寻找两个分支最近的分割点,即base.假设git 树是多叉树,请实现一个算法,计算git树上任意两点的最近分割点。 (假设git树节点数为n,用邻接矩阵的形式表示git树:字符串数组matrix包含n个字符串,每个字符串由字符'0

    // ConsoleApplication10.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream& ...

  2. 开源监控软件ganglia

    开源监控软件ganglia安装手册 Ganglia是一个监控服务器,集群的开源软件,能够用曲线图表现最近一个小时,最近一天,最近一周,最近一月,最近一年的服务器或者集群的cpu负载,内存,网络,硬盘等 ...

  3. 17 redis -key设计原则

    书签系统 create table book ( bookid int, title char(20) )engine myisam charset utf8; insert into book va ...

  4. java 邮件(2)

    /**  * 方法描述:发送带附件的邮件  *   * @throws UnsupportedEncodingException  */  public static boolean sendEmai ...

  5. 利用Docker Compose快速搭建本地测试环境

    前言 Compose是一个定义和运行多个Docker应用的工具,用一个YAML(dockder-compose.yml)文件就能配置我们的应用.然后用一个简单命令就能启动所有的服务.Compose编排 ...

  6. python 基础 9.3 mysql 数据操作

    #/usr/bin/python #coding=utf-8 #@Time   :2017/11/21 0:20 #@Auther :liuzhenchuan #@File   :mysql 数据操作 ...

  7. EasyNVR RTSP转RTMP-HLS流媒体服务器前端构建之:内部搜索功能的实现

    上一篇介绍了处理接口获取的数据,本篇将介绍如何在接收到的数据中搜索出自己符合条件的数据: 为了页面的美观,我们往往会以分页的形式来进行数据的展示.但是,当需要展示出来的数据太多的时候,我们很难迅速的找 ...

  8. Java中如何判断一个日期字符串是否是指定的格式

    判断日期格式是否满足要求 import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date ...

  9. 怎样拆分View Controller进而实现轻量级的View Controller[UIKit]

    參考文章来自objcio站点   为什么要编写轻量级的View Controller??   1.作为iOS项目中最大的文件,ViewControllers中的代码复用率差点儿是最低的 2.重量级的V ...

  10. php+mysql 安全

    Php注入攻击是现今最流行的攻击方式,依靠它强大的灵活性吸引了广大黑迷. 在上一期的<php安全与注射专题>中林.linx主要讲述了php程序的各种漏洞,也讲到了php+mysql注入的问 ...