j\u0011\u0011!a\u0001G\u000511m\u001c7pe\u0002\nQa\u001d;beR\u0004"
)
public class Car {
private String brand;
private double price;
public static void start() {
Car$.MODULE$.start();
}
public static void color_$eq(final String x$1) {
Car$.MODULE$.color_$eq(var0);
}
public static String color() {
return Car$.MODULE$.color();
}
public String brand() {
return this.brand;
}
public void brand_$eq(final String x$1) {
this.brand = x$1;
}
public double price() {
return this.price;
}
public void price_$eq(final double x$1) {
this.price = x$1;
}
public void sayHello() {
.MODULE$.println("hello");
}
public Car(final String brand, final double price) {
this.brand = brand;
this.price = price;
super();
}
}
//decompiled from Car$.class
package com.doit.day01.day02;
import scala.Predef.;
public final class Car$ {
public static Car$ MODULE$;
private String color;
static {
new Car$();
}
public String color() {
return this.color;
}
public void color_$eq(final String x$1) {
this.color = x$1;
}
public void start() {
.MODULE$.println("汽车启动了,嗡~~~~~~~~");
}
private Car$() {
MODULE$ = this;
this.color = "red";
}
}
图示:
伴生对象用途:
- 可以将静态的成员变量和普通成员变量分别声明(class中没办法添加静态成员,需要经过object类来添加)
- 伴生对象自己内部定义了一个apply方法,可以简化创建对象(类的实例构造)
- 伴生对象自己定义了一个unapply方法,可以用于模式匹配
apply方法
使用此方法时,可以在main函数中不通过new来创建一个对象,即可以不用专门的一次一次地进行实例化,加载创建对象的这个类的时候,会自动调用apply这个方法,类似Java中的static静态块。
- 通过伴生对象的 apply 方法,实现不使用 new 方法创建对象。
- apply 方法可以重载。
- Scala 中 obj(arg)的语句实际是在调用该对象的 apply 方法,即 obj.apply(arg)。用以统一面向对象编程和函数式编程的风格。
- 当使用 new 关键字构建对象时,调用的其实是类的构造方法,当直接使用类名构建对象时,调用的其实是伴生对象的 apply 方法。
object Test {
def main(args: Array[String]): Unit = {
//(1)通过伴生对象的 apply 方法,实现不使用 new 关键字创建对象。
val p1 = Person()
println("p1.name=" + p1.name)
val p2 = Person("bobo")
println("p2.name=" + p2.name)
}
}
//(2)如果想让主构造器变成私有的,可以在()之前加上 private
class Person private(cName: String) {
var name: String = cName
}
object Person {
def apply(): Person = {
println("apply 空参被调用")
new Person("xx")
}
def apply(name: String): Person = {
println("apply 有参被调用")
new Person(name)
}
}
权限修饰符
在 Java 中,访问权限分为:public,private,protected 和默认。在 Scala 中,你可以通过类似的修饰符达到同样的效果。但是使用上有区别。
(1)Scala 中属性和方法的默认访问权限为 public,但 Scala 中无 public 关键字。
(2)private 为私有权限,只在类的内部和伴生对象中可用。
(3)protected 为受保护权限,Scala 中受保护权限比 Java 中更严格,同类、子类可以访问,同包无法访问。
(4)private[包名]增加包访问权限,包名下的其他类也可以使用
代码演示:
class Person {
private var name: String = "bobo"
protected var age: Int = 18
private[test] var sex: String = "男"
def say(): Unit = {
println(name)
}
}
object Person {
def main(args: Array[String]): Unit = {
val person = new Person
person.say()
println(person.name)
println(person.age)
}
}
class Teacher extends Person {
def test(): Unit = {
this.age
this.sex
}
}
class Animal {
def test: Unit = {
new Person().sex
}
}
特质和抽象类
特质
Trait(特质)相当于 java 的接口。比接口功能更强大。特质中可以定义属性和抽象方法和方法的实现。
Scala 的类只能够继承单一父类,但是可以实现(继承,混入)多个特质(Trait),使用的关键字是 with 和 extends
注意,特质不能有主构造函数
基本语法
trait 特质名 {
trait 主体
}
如何使用特质:
没有父类:class 类名 extends 特质 1 with 特质 2 with 特质 3 …
有父类:class 类名 extends 父类 with 特质 1 with 特质 2 with 特质 3…
代码演示:
trait PersonTrait {
// 声明属性
var name:String = _
// 声明方法
def eat():Unit={
}
// 抽象属性
var age:Int
// 抽象方法
def say():Unit
}
特质的本质就是抽象类+接口
特