-
包
-
import
-
类_属性
类在编译后,类中会生成属性的set、get方法,在赋值或调用时会调用两个方法
加了@BeanProperty的属性,对象可以通过get、set方法操作 -
访问权限
-
方法
Scala中的类的方法就是函数,所以声明方式完全一样,但是必须通过使用对象进行调用。
方法的重写:遵循动态绑定机制,即调用对象成员方法的过程中,方法会与对象的实际内存进行绑定(即new的类型是什么,对象的实际内存就是什么),因此调用的方法父类子类都存在时,看new的类型进行方法,对于属性不遵循动态绑定机制,进入了哪个类中的方法就用哪个类中的属性(如果属性名重名的话) -
对象
Scala中的对象用Var | Val修饰
val | var 对象名 :类型 = new 类型()
在java里面,定义构造方法,就是定义一个没有返回值类型的与类同名的方法。
scala的构造函数由一个主构造函数和0到多个辅助构造函数组成。每个类都有主构造函数,和类的定义交织在一起。
scala的主构造函数指的是整个类,主要包含以下几个部分:
(1)构造函数参数;
主构造函数里的参数,如果不声明为var或者val,则该参数只能被当做一个类内不可变参数使用,不能被当做类的字段,既外部不能访问该变量。
当为主构造函数的的参数添加var,或者val声明,则该参数被升级为类的成员变量。
(2)在类内部被调的方法;
(3)在类内部执行的语句和表达式。
辅助构造函数:
辅助构造函数函数名为this,辅助构造函数的第一个语句必须为对主构造函数的调用
构造方法私有化:参数列表前面加private关键字
6.2伴生对象
伴生类和伴生对象在同一个文件中,名字相同,class类称为object的伴生类,object称为class的伴生对象。
伴生对象是马丁为了模拟java中的静态语法创造的,一般写代码时,将静态语法操作的代码写在伴生对象中,将成员方法或属性写在伴生类中。Main方法也可以认为静态的。
伴生类中可以声明无参构造器和有参构造器,辅助构造器,属性,方法。
伴生对象属于单例对象,也可以声明属性,方法,但是不可以声明构造器。
Test()调用的伴生对象apply方法结果与new Test()一致,Test()是伴生对象本体
在一个scala文件中,如aaa.scala
文件名与其他对象名,类名无关(这点与java不同),其次,这个文件中可以同时存在普通类、伴生类,伴生对象等。
apply()方法
实现在伴生对象中的一种方法,是个语法糖,方便创建对象。(实际就是通过伴生类构造器new出对象,当然还可以加别的代码语句),属于伴生类与伴生对象间的桥梁。
1、单例对象与同名类定义在同一文件中时形成绑定关系
同名类称为单例对象的伴生类(class)
单例对象称为同名类伴生对象(object)
2、伴生类与伴生对象可相互访问各自私有成员(包括私有构造器,伴生对象无构造器)
3、伴生对象可为伴生类增加静态成员(反编译会有两个类
class Person (name:String){
val username = name // 可把参数变成变量
def this() {
this("wjj")
}
def printMsg(): Unit = {
Person.showMsg(this) // 相当于Person.apply().showMsg()
}
}
object Person {
def apply(name:String): Person = new Person(name)
def showMsg(p:Person): Unit = {
println(p.username)
}
def main(args: Array[String]): Unit = {
// 使用object的apply方法新建对象,只能使用class中的属性和方法
val p1 = Person("zhangsan") // 相当于Person.apply("zhangsan")
Person.showMsg(p1) // 使用Person对象调用伴生对象中的方法
// 使用构造方法
val p2:Person = new Person()
var p11 = Person // Person就是伴生对象本身
p2.printMsg() // class new出来的对象只能使用class中的属性和方法
p11.showMsg(p1)
}
}
-
面向对象三大特性
单继承,extends关键字
封装:属性私有化,提供公共get、set方法
抽象:抽象类(不完整的类),含抽象方法或抽象属性(不声明没实现,没初始化)
注意点:
抽象类中的完整属性不能是可变的。即初始化的属性只能val修饰
完整属性的重写要加override关键字,开发一般只要是重写都加
抽象属性反编译后其实没有属性,只有该属性的get、set方法,所以也相当于抽象方法 -
特征
关键字trait,理解为接口与抽象类的结合体
(1)混入
类名extends trait1 with trait2 with trait3 // 类名extends 类 with trait
(2)动态混入
New User() with 特征
trait Operator {
def operateData(): Unit = {
println("操作数据")
}
}
trait DB extends Operator {
override def operateData(): Unit = {
print("向数据库中")
super.operateData()
}
}
trait Log extends Operator {
override def operateData(): Unit = {
print("向日志文件中")
super.operateData()
}
}
class MySQL extends DB with Log {
}
object Scala01_Trait {
def main(args: Array[String]): Unit = {
new MySQL().operateData() // 会从外层的Log类开始打印
}
}
- 扩展
(1)判断对象是否为某个类型的实例、将对象转换为某个类型的实例
val bool: Boolean = person.isInstanceOf[Person]
val p1: Person = person.asInstanceOf[Person]
(2)获取类信息
(3)枚举类和应用类
object对象是某个类的单例实现,它的应用包括作为伴生对象、继承抽象类、实现main方法、实现枚举值
object Color extends Enumeration {
val RED = Value(1, "red")
val YELLOW = Value(2, "yellow")
val BLUE = Value(3, "blue")
}
object Test {
def main(args: Array[String]): Unit = {
println(Color.RED.id) // 1
}
}
APP类:作用是当object继承它时,不需要写main方法,而是将整个的类看做一个main方法。
type关键字:可以给类型取别名如:type S = String
10.单例模式(拓展)
单例模式提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
主要解决:一个全局使用的类频繁地创建与销毁。
何时使用:当您想控制实例数目,节省系统资源的时候。
如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。
关键代码:构造函数是私有的。
(1)懒汉式,线程不安全,多线程不能工作,获取实例后实例才成为静态
public class Singleton {
private static Singleton instance; // 静态方法中只能返回静态实例,所以要加static
private Singleton (){} // 构造器私有
public static Singleton getInstance() { // 获取实例的方法(static后加synchronized安全)
if (instance == null) {
instance = new Singleton();
}
return instance;
(2)饿汉式,线程安全,常用,实例在类加载时就实例化,浪费内存,类加载机制避免了多线程的同步问题
public class Singleton {
private static Singleton instance = new Singleton(); // static是为了类加载时就产生实例
private Singleton (){}
public static Singleton getInstance() { // static是因为调用是直接通过类名调用的
return instance;
}
}
Non-static field cannot be referenced from a static context 非静态字段不能从静态上下文引用
对于属性、方法加不加static完全看上下文。