类和对象

组成结构
• 构造函数: 在创建对象的时候给属性赋值
• 成员变量:
• 成员方法(函数)
• 局部变量
• 代码块

构造器

每个类都有一个主构造器,这个构造器和类定义"交织"在一起类名后面的内容就是主构造器,如果参数列表为空的话,()可以省略
scala的类有且仅有一个主构造器,要想提供更加丰富的构造器,就需要使用辅助构造器,辅助构造器是可选的,它们叫做this def this
注意:主构造器会执行类定义中的所有语句
代码示例:

// 类默认有一个无参的主构造函数
class User { 
}

val user: User = new User

// 两个参数的主构造函数
class User2(val name: String, age: Int) { 

}
val user2 = new User2("jim", 23)
// 使用val修饰的变量默认是成员变量,对象可以访问
// user2.age   // age没有使用val或者var修饰 所以不能被访问,他不是一个成员变量,而是一个局部变量


//辅助构造器
class User3 {
   var name: String = _
   var age: Int = _
  // 辅助构造函数
  def this(name: String, age: Int) {
    // 构造函数中的首行必须调用主构造函数或者其他构造函数
    this()
    this.name = name
    this.age = age
  }
  // 辅助构造函数
  def this(msg: String) = {
    // 首行调用一个构造
    this("ww", 12)
    println(msg)
  }
}
val u1 = new User3()
val u2 = new User3("")
val u3 = new User3("lisi", 23)
println(u3.name)

总结:

  1. 有两类构造器:主构造器,辅助构造器
  2. 构造器的定义位置:主构造器和类交织在一起,class Student2(val name: String, var age: Int)
  3. 辅助构造器是一个特殊的方法,定义在类中 def this(name:String,age:Int,gender:String)
  4. 辅助构造器,第一行必须调用主构造器(或者其他的辅助构造器)
  5. 辅助构造器的参数不能和主构造器的参数完全一致(参数个数,参数类型,参数顺序)
  6. 可以定义空参的辅助构造器,但是主构造器的参数必须进行初始化赋值
  7. 作用域:辅助构造器的变量作用域,只在方法中,主构造器的作用域是类中除了成员属性和成员方法之外的所有范围(可以通过反编译查看源码)

构造器的参数说明

  • 主构造函数中使用val 和 var修饰的变量为成员变量
  • val 修饰的变量默认只有getter方法 一要初始化
  • var 修饰的变量默认有 get和set方法 直接点属性操作 使用 _ 占位可以稍后赋值
  • @BeanProperty会生成getMsg setMsg方法

成员方法/函数

在类的成员位置定义的函数或者方法是类的成员的一部分

代码块

在类或者对象中的代码块在实例化的时候会被调用

  • 在类成员位置的代码块 构造代码块 每次创建对象都会执行一次
  • 在object中成员位置的代码块是静态代码块 只执行一次
  • 代码有返回值

object类的底层原理

package com.doit.day01.day02

//如果构造器中的变量,不加var 或者val 那他就是一个局部变量
//加了var 或者val 的话他就是一个私有的成员变量
class Student1(var id: Int, val name: String) {

  def sayHello: Unit = {
    println(name + ":你好")
  }

  val sayFunc = () => {
    println("hello:" + name)
  }
}


object Student2{
  var id: Int = 1
  //如果在成员变量的位置上给一个_作为占位符,相当于是给他赋了一个默认值啊
  var name: String =_

  def sayHello: Unit = {
    println(name + ":你好")
  }
  val sayFunc = (x:String) => {
    println("hello:" + name + x)
  }
}


object Demo01_面向对象 {
  def main(args: Array[String]): Unit = {

    Student2.sayFunc("a")

    val student1: Student1 = new Student1(1, "zhangsan")
    println(student1.name)
    println(student1.id)
    //    student1.name = "lisi"  用val 修饰的,不能修改
    student1.id = 2
    println(student1.id)

    student1.sayHello
    student1.sayFunc()
    println(Student2.name)
  }
}

java手写实现:

package com.doit;


public class Person {
    public static String getName(){
        return Person$.person.getName();
    }

    public static Integer getAge(){
        return Person$.person.getAge();
    }

    public static void setName(String name ){
        Person$.person.setName(name);
    }

    public static void setAge(Integer age ){
        Person$.person.setAge(age);
    }
}

class Person$ {
    //自己的对象
    public static Person$ person ;
    //成员变量
    private String name;
    private int age;

    static {
        person  = new Person$();
    }

    private Person$() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}


class Test{
    public static void main(String[] args) {
        Person person = new Person();
        person.setName("张三");
        person.setAge(18);
        String name1 = person.getName();
        Integer age1 = person.getAge();
        System.out.println(name1);
        System.out.println(age1);
    }
}

scala中底层反编译后的代码:

package com.doit.day01.day02;

import java.lang.invoke.SerializedLambda;
import scala.Function1;
import scala.Predef.;
import scala.runtime.BoxedUnit;

public final class Student2$ {
   public static Student2$ MODULE$;
   private int id;
   private String name;
   private final Function1 sayFunc;

   static {
      new Student2$();
   }

   public int id() {
      return this.id;
   }

   public void id_$eq(final int x$1) {
      this.id = x$1;
   }

   public String name() {
      return this.name;
   }

   public void name_$eq(final String x$1) {
      this.name = x$1;
   }

   public void sayHello() {
      .MODULE$.println((new StringBuilder(3)).append(this.name()).append(":你好").toString());
   }

   public Function1 sayFunc() {
      return this.sayFunc;
   }

// $FF: synthetic method
   public static final void $anonfun$sayFunc$1(final String x) {
      .MODULE$.println((new StringBuilder(6)).append("hello:").append(MODULE$.name()).append(x).toString());
   }

   private Student2$() {
      MODULE$ = this;
      this.id = 1;
      this.sayFunc = (x) -> {
         $anonfun$sayFunc$1(x);
         return BoxedUnit.UNIT;
      };
   }

// $FF: synthetic method
   private static Object $deserializeLambda$(SerializedLambda var0) {
      return var0.lambdaDeserialize<invokedynamic>(var0);
   }
}

 //decompiled from Student2.class
package com.doit.day01.day02;

import scala.Function1;
import scala.reflect.ScalaSignature;

@ScalaSignature(
   bytes = "u0006u0001!;Qu0001Du0007tu0002Y1Qu0001Gu0007tu0002eAQu0001Iu0001u0005u0002u0005BqAIu0001Au0002u0013u00051u0005Cu0004(u0003u0001u0007Iu0011u0001u0015tr9nu0001u0015)u0003%u0011%yu0013u00011AAu0002u0013u0005u0001u0007Cu0005=u0003u0001u0007tu0019!Cu0001{!Iq(u0001au0001u0002u0003u0006K!ru0005u0006u0001u0006!t!u0011u0005bu0005u0006u0011ru0011"u0001Du0011u00199u0015u0001)Au0005tu0006A1u000b^;eK:$(Gu0003u0002u000fu001fu0005)A-Y=1e)u0011u0001#Eu0001u0006Iu0006Lb'ru0006u0003%MtAu0001Z8ji*tA#Au0002d_6u001cu0001u0001u0005u0002u0018u00035tQBu0001u0005TiV$WMu001c;3'tt!u0004u0005u0002u001c=5tADCu0001u001eu0003u0015u00198-u00197bu0013tyBDu0001u0004B]fu0014VMZu0001u0007y%tu0017u000eu001e u0015u0003Yt!!u001b3u0016u0003u0011u0002"aGu0013nu0005u0019b"aA%oiu00061u0011u000eZ0%KF$"!u000bu0017u0011u0005mQu0013BAu0016u001du0005u0011)f.u001b;tu000f5"u0011u0011!au0001Iu0005u0019u0001u0010Ju0019u0002u0007%$u0007%u0001u0003oC6,W#Au0019u0011u0005IJdBAu001a8!t!D$Du00016u0015t1T#u0001u0004=e>|GOPu0005u0003qqtau0001u0015:fIu00164u0017Bu0001u001e<u0005u0019u0019FO]5oO*u0011u0001bHu0001t]u0006lWmu0018u0013fcRu0011u0011Fu0010u0005b[u001dttu00111u00012u0003u0015qu0017-\3!u0003!u0019u0018-u001f%fY2|W#Au0015u0002u000fMfu0017PR;oGVtAtu0005u0003u001cu000bFJu0013Bu0001$u001du0005%1UO\2uS>tu0017'u0001u0005tCf4UO\2!u0001"
)
public final class Student2 {
   public static Function1 sayFunc() {
      return Student2$.MODULE$.sayFunc();
   }

   public static void sayHello() {
      Student2$.MODULE$.sayHello();
   }

   public static void name_$eq(final String x$1) {
      Student2$.MODULE$.name_$eq(var0);
   }

   public static String name() {
      return Student2$.MODULE$.name();
   }

   public static void id_$eq(final int x$1) {
      Student2$.MODULE$.id_$eq(var0);
   }

   public static int id() {
      return Student2$.MODULE$.id();
   }
}

伴生类和伴生对象

条件 1:在同一个源文件中, 条件 2:对象名和类名相同

  //类名和object的名称一致
  //类是对象的伴生类
  //对象是类的伴生对象

class Demo6(val name: String) {
}
object Demo6 {
}

条件 2:伴生对象和伴生类之间可以互相访问彼此的私有属性和私有方法

package com.doit.day01.day02

/**
 * 伴生对象的用途:
 *      1.可以将静态的成员变量和普通成员变量分别声明
 *      2.伴生对象自己内部定义了一个apply方法,可以简化创建对象(类的实例构造)
 *      3.伴生对象自己定义了一个unapply方法,可以用于模式匹配
 */
class Car(var brand: String, var price: Double) {

  def sayHello(): Unit ={
    println("hello")
  }

  private val color: String = Car.color
  Car.start()
}


object Car {
  var color :String = "red"

  def start(): Unit ={
    println("汽车启动了,嗡~~~~~~~~")
  }
}

object Demo02_伴生对象 {
  def main(args: Array[String]): Unit = {
    val car: Car = new Car("华为", 9.9)
    println(car.brand)
    println(car.price)
    car.sayHello()
    Car.start()
  }
}

伴生对象的底层原理:

//decompiled from Car.class
package com.doit.day01.day02;

import scala.Predef.;
import scala.reflect.ScalaSignature;

@ScalaSignature(
   bytes = "u0006u0001E3Au0001Etu00015!Au0011u0005u0001BAu0002u0013u0005!u0005u0003u0005/u0001tu0005ru0011"u00010u0011!)u0004A!A!Bu0013u0019u0003u0002u0003u001cu0001u0005u0003u0007Iu0011Au001ctu0011mu0002!u00111Au0005u0002qBu0001Bu0010u0001u0003u0002u0003u0006Ku0001u000fu0005u0006u007fu0001!tu0001u0011u0005u0006u000bu0002!tARu0004u0006u000fFAtu0001u0013u0004u0006!EAt!u0013u0005u0006u007f)!tAu0013u0005bu0017*u0001ru0011"u0001#u0011u001da%u00021Au0005u00025Caau0014u0006!Bu0013u0019u0003"u0002)u000btu00031%aA"be*u0011!cEu0001u0006Iu0006LbGru0006u0003)UtQu0001Z1zaER!AFfu0002tu0011|u0017u000eu001eu0006u00021u0005u00191m\7u0004u0001Mu0011u0001au0007tu00039}iu0011!bu0006u0002=u0005)1oY1mC&u0011u0001%bu0002u0007u0003:L(+u001a4u0002u000btu0014u0018Mu001c3u0016u0003ru0002"u0001Ju0016u000fu0005u0015Ju0003Cu0001u0014u001eu001bu00059#Bu0001u0015u001au0003u0019a$o\8u}%u0011!&Hu0001u0007!J,G-u001a4nu00051j#AB*ue&twMu0003u0002+;u0005I!M]1oI~#S-u001du000bu0003aMu0002"u0001Hu0019nu0005Ij"u0001B+oSRDqu0001u000eu0002u0002u0002u0003u00071%Au0002yIEnaAu0019:b]u0012u0004u0013!u00029sSu000e,W#u0001u001du0011u0005qIu0014Bu0001u001eu001eu0005u0019!u.u001e2mKu0006Iu0001O]5dK~#S-u001du000bu0003auBqu0001Nu0003u0002u0002u0003u0007u0001(u0001u0004qe&u001cWrIu0001u0007y%tu0017u000eu001e u0015u0007u0005u001bEtu0005u0002Cu00015tu0011u0003Cu0003"u000fu0001u00071u0005Cu00037u000fu0001u0007u0001(u0001u0005tCfDUru001c7p)u0005u0001u0014aA"beBu0011!ICnu0003u0015m!u0012u0001Su0001u0006G>dwN]u0001nG>dwN]0%KF$"u0001r(tu000fQju0011u0011!au0001Gu000511mu001c7peu0002nQau001d;beRu0004"
)
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";
   }
}

图示:

image
伴生对象用途:

  1. 可以将静态的成员变量和普通成员变量分别声明(class中没办法添加静态成员,需要经过object类来添加)
  2. 伴生对象自己内部定义了一个apply方法,可以简化创建对象(类的实例构造)
  3. 伴生对象自己定义了一个unapply方法,可以用于模式匹配

apply方法

使用此方法时,可以在main函数中不通过new来创建一个对象,即可以不用专门的一次一次地进行实例化,加载创建对象的这个类的时候,会自动调用apply这个方法,类似Java中的static静态块。

  1. 通过伴生对象的 apply 方法,实现不使用 new 方法创建对象。
  2. apply 方法可以重载。
  3. Scala 中 obj(arg)的语句实际是在调用该对象的 apply 方法,即 obj.apply(arg)。用以统一面向对象编程和函数式编程的风格。
  4. 当使用 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
}

特质的本质就是抽象类+接口

特质的动态混入

1.创建对象时混入 trait,而无需使类混入该 trait
2.如果混入的 trait 中有未实现的方法,则需要实现
代码演示:

trait PersonTrait {
 //(1)特质可以同时拥有抽象方法和具体方法
 // 声明属性
 var name: String = _
 // 抽象属性
 var age: Int
 // 声明方法
 def eat(): Unit = {
 println("eat")
 }
 // 抽象方法
 def say(): Unit
}
trait SexTrait {
 var sex: String
}
//(2)一个类可以实现/继承多个特质
//(3)所有的 Java 接口都可以当做 Scala 特质使用
class Teacher extends PersonTrait with java.io.Serializable {
 override def say(): Unit = {
 println("say")
 }
 override var age: Int = _
}
object TestTrait {
 def main(args: Array[String]): Unit = {
 val teacher = new Teacher
 teacher.say()
 teacher.eat()
 //(4)动态混入:可灵活的扩展类的功能
 val t2 = new Teacher with SexTrait {
 override var sex: String = "男"
 }
 //调用混入 trait 的属性
 println(t2.sex)
 } 
}

抽象类

在 Scala 中, 使用 abstract 修饰的类称为抽象类. 在抽象类中可以定义属性、未实现的方法(抽象方法)和具体实现的方法。 含有抽象方法的类就是抽象类

  • 抽象类中的属性
  • 抽象方法
  • 具体实现的方法
  • 类的单继承

示例:

/*
* abstract 修饰的类是一个抽象类
* */
abstract class Animal {
  println("Animal's constructor ....")
  // 定义一个 name 属性
  val name: String = "animal"
  // 没有任何实现的方法
  def sleep()
  // 带有具体的实现的方法
  def eat(f: String): Unit = {
    println(s"$f")
    }
  }

抽象类的继承和重写

  • 如果父类为抽象类,那么子类要么也是抽象类,要么就需要重写父类中的所有的抽象方法和抽象的成员变量
  • 重写非抽象方法需要用 override 修饰,重写抽象方法则可以不加 override。
  • 子类中调用父类的方法使用 super 关键字,在子类重写了父类的方法后,如果不加super,直接写方法名调用的就是子类重写后的,如果加了,调用的还是父类的
  • 子类对抽象属性进行实现,父类抽象属性可以用 var 修饰;子类对非抽象属性重写,父类非抽象属性只支持 val 类型,而不支持 var(var修饰具体方法和变量不好重写)

因为 var 修饰的为可变变量,子类继承之后就可以直接使用,没有必要重写

样例类

使用case修饰的类就是样例类(封装数据,模式匹配)

  1. 构造器中的参数默认是val修饰的[成员,赋值1次]
  2. 样例类会自动创建伴生对象, 同时在里面实现;的apply和unapply方法 ,创建对象的时候不用new
  3. 很好的支持匹配模式
  4. 默认实现了自己的toString , hashCode , copy , equals,序列化方法

定义一个样例类:

case class Person(var name:String , var age:Int){}
//如果类中没有别的需要定义的,可以不写大括号

反编译之后的结果:

//decompiled from Person$.class
package com.doit.day01.day02;

import scala.Option;
import scala.Serializable;
import scala.Some;
import scala.Tuple2;
import scala.None.;
import scala.runtime.AbstractFunction2;
import scala.runtime.BoxesRunTime;

public final class Person$ extends AbstractFunction2 implements Serializable {
   public static Person$ MODULE$;

   static {
      new Person$();
   }

   public final String toString() {
      return "Person";
   }

   public Person apply(final String name, final int age) {
      return new Person(name, age);
   }

   public Option unapply(final Person x$0) {
      return (Option)(x$0 == null ? .MODULE$ : new Some(new Tuple2(x$0.name(), BoxesRunTime.boxToInteger(x$0.age()))));
   }

   private Object readResolve() {
      return MODULE$;
   }

   // $FF: synthetic method
   // $FF: bridge method
   public Object apply(final Object v1, final Object v2) {
      return this.apply((String)v1, BoxesRunTime.unboxToInt(v2));
   }

   private Person$() {
      MODULE$ = this;
   }
}

        //decompiled from Person.class
package com.doit.day01.day02;

import scala.Function1;
import scala.Option;
import scala.Product;
import scala.Serializable;
import scala.collection.Iterator;
import scala.reflect.ScalaSignature;
import scala.runtime.BoxesRunTime;
import scala.runtime.Statics;
import scala.runtime.ScalaRunTime.;

@ScalaSignature(
   bytes = "u0006u0001u0005Ucu0001u0002u000eu001cu0001u0012Bu0001"ru0001u0003u0012u0004%tAru0005t}u0001u0011tu0019!Cu0001u007f!AQtu0001BtBu0003&1u0007u0003u0005Gu0001tEru0011"u0001Hu0011!Yu0005A!au0001nu0003au0005u0002u0003(u0001u0005#u0005u000bu0015u0002%tu000b=u0003Au0011u0001)tu000fUu0003u0011u0011!Cu0001-"9u0011fAIu0001nu0003Qu0006bB3u0001#u0003%tAu001au0005bQu0002ttu0011"u0011ju0011u001dtb!!Au0005u0002u001dCqAu001du0001u0002u0002u0013u00051u000fCu0004yu0001u0005u0005Iu0011I=tu0013u0005u0005u0001!!Au0005u0002u0005ru0001"CAu0007u0001u0005u0005Iu0011IAbu0011%ttu0002AAu0001nu0003nu0019u0002Cu0005u0002u0016u0001ttu0011"u0011u0002u0018u001dIu00111Du000eu0002u0002#u0005u0011Qu0004u0004t5mttu0011#u0001u0002 !1qnu0006Cu0001u0003[Au0011"!u0005u0015u0003u0003%)%au0005tu0013u0005=B#!Au0005u0002u0006Eu0002"CAu001c)u0005u0005Iu0011QAu001du0011%tYu0005FAu0001nu0013tiEu0001u0004QKJu001cxNu001cu0006u00039utQu0001Z1zaIR!AHu0010u0002u000bu0011fu0017u0010Mu0019u000bu0005u0001nu0013u0001u00023pSRTu0011AIu0001u0004G>l7u0001Anu0005u0001u0015Zcu0006u0005u0002'S5tqECu0001)u0003u0015u00198-u00197bu0013tQsEu0001u0004B]fu0014VMu001atu0003M1J!!Lu0014u0003u000fAu0013xu000eZ;diBu0011aeLu0005u0003au001du0012AbU3sSu0006du0017N_1cYu0016fAA\1nKVt1u0007u0005u00025w9u0011Q'u000ftu0003mu001dju0011au000eu0006u0003qrnau0001u0010:p_Rtu0014Bu0001u001e(u0003u0019u0001&/u001a3fM&u0011A(u0010u0002u0007'Ru0014u0018N\4u000bu0005i:u0013u0001u00038b[u0016|F%Z9u0015u0005u0001u001bu0005Cu0001u0014Bu0013tu0011uEu0001u0003V]&$bbu0002#u0003u0003u0003u0005raMu0001u0004qu0012nu0014!u00028b[u0016u0004u0013aA1hKVtu0001nu0005u0002'u0013&u0011!jnu0002u0004u0013:$u0018aB1hK~#S-u001du000bu0003u00016Cqu0001Ru0003u0002u0002u0003u0007u0001*u0001u0003bOu0016u0004u0013Au0002u001fj]&$hbFu0002R'Ru0003"Au0015u0001u000eu0003mAQ!Mu0004Au0002MBQARu0004Au0002!u000bAaY8qsRu0019u0011ku0016-tu000fEBu0001u0013!au0001g!9atu0003Iu0001u0002u0004Au0015AD2paf$C-u001a4bk2$H%Mu000bu00027*u00121u0007Xu0016u0002;Bu0011alYu0007u0002?*u0011u0001-Yu0001nk:u001cu0007.Z2lKu0012T!AYu0014u0002u0015u0005tgnu001c;bi&|g.u0003u0002e?ntRO\2iKu000e\Wru001a,be&fgnY3u0002u001dr|u0007/u001fu0013eKu001afWu000fu001c;%eUtqMu000bu0002I9u0006iu0001O]8eku000e$bK]3gSb,u0012Au001btu0003WBlu0011u0001u001cu0006u0003[:fAu0001\1oO*tq.u0001u0003kCZfu0017Bu0001u001fmu00031u0001(ou001c3vGRf%/u001b;zu00039u0001(ou001c3vGR,E.Z7f]R$"u0001^<u0011u0005u0019*u0018Bu0001<(u0005rte.u001fu0005bt6ttu00111u0001Iu0003=u0001(ou001c3vGRLE/u001a:bi>u0014X#u0001>u0011u0007mtH/Du0001}u0015tix%u0001u0006d_2dWmu0019;j_:L!a ?u0003u0011%#XM]1u_Jfu0001bY1ou000bF,u0018ru001cu000bu0005u0003u000btYu0001Eu0002'u0003u000fI1!!u0003(u0005u001du0011unu001c7fC:Dqu0001Rbu0002u0002u0003u0007A/u0001u0005iCND7iu001c3f)u0005Au0015u0001u0003;p'Ru0014u0018N\4u0015u0003)fa!Z9vC2u001cHu0003BAu0003u00033Aqu0001u0012nu0002u0002u0003u0007A/u0001u0004QKJu001cxNu001ctu0003%Ru0019Bu0001FAu0011]A9u00111EAu0015g!u000bVBAAu0013u0015rt9cJu0001beVtG/[7fu0013u0011tY#!nu0003#u0005u00137u000fu001e:bGR4UO\2uS>t'u0007u0006u0002u0002u001eu0005)u0011ru001d9msR)u0011+aru00026!)u0011gu0006au0001g!)aiu0006au0001u0011u00069QO\1qa2LHu0003BAu001eu0003u000fu0002RAJAu001fu0003u0003J1!au0010(u0005u0019yu0005u000f^5p]B)a%au00114u0011&u0019u0011QIu0014u0003rQ+bu000f\33u0011!tIu0005GAu0001u0002u0004tu0016au0001=%au0005Y!/Z1e%u0016u001cxu000eu001c<f)ttyu0005Eu0002lu0003#J1!au0015mu0005u0019y%M[3diu0002"
)
public class Person implements Product, Serializable {
   private String name;
   private int age;

   public static Option unapply(final Person x$0) {
      return Person$.MODULE$.unapply(var0);
   }

   public static Person apply(final String name, final int age) {
      return Person$.MODULE$.apply(var0, var1);
   }

   public static Function1 tupled() {
      return Person$.MODULE$.tupled();
   }

   public static Function1 curried() {
      return Person$.MODULE$.curried();
   }

   public String name() {
      return this.name;
   }

   public void name_$eq(final String x$1) {
      this.name = x$1;
   }

   public int age() {
      return this.age;
   }

   public void age_$eq(final int x$1) {
      this.age = x$1;
   }

   public Person copy(final String name, final int age) {
      return new Person(name, age);
   }

   public String copy$default$1() {
      return this.name();
   }

   public int copy$default$2() {
      return this.age();
   }

   public String productPrefix() {
      return "Person";
   }

   public int productArity() {
      return 2;
   }

   public Object productElement(final int x$1) {
      Object var10000;
      switch(x$1) {
      case 0:
         var10000 = this.name();
         break;
      case 1:
         var10000 = BoxesRunTime.boxToInteger(this.age());
         break;
      default:
         throw new IndexOutOfBoundsException(BoxesRunTime.boxToInteger(x$1).toString());
      }

      return var10000;
   }

   public Iterator productIterator() {
      return .MODULE$.typedProductIterator(this);
   }

   public boolean canEqual(final Object x$1) {
      return x$1 instanceof Person;
   }

   public int hashCode() {
      int var1 = -889275714;
      var1 = Statics.mix(var1, Statics.anyHash(this.name()));
      var1 = Statics.mix(var1, this.age());
      return Statics.finalizeHash(var1, 2);
   }

   public String toString() {
      return .MODULE$._toString(this);
   }

   public boolean equals(final Object x$1) {
      boolean var6;
      if (this != x$1) {
         label55: {
            boolean var2;
            if (x$1 instanceof Person) {
               var2 = true;
            } else {
               var2 = false;
            }

            if (var2) {
               label38: {
                  label37: {
                     Person var4 = (Person)x$1;
                     String var10000 = this.name();
                     String var5 = var4.name();
                     if (var10000 == null) {
                        if (var5 != null) {
                           break label37;
                        }
                     } else if (!var10000.equals(var5)) {
                        break label37;
                     }

                     if (this.age() == var4.age() && var4.canEqual(this)) {
                        var6 = true;
                        break label38;
                     }
                  }

                  var6 = false;
               }

               if (var6) {
                  break label55;
               }
            }

            var6 = false;
            return var6;
         }
      }

      var6 = true;
      return var6;
   }

   public Person(final String name, final int age) {
      this.name = name;
      this.age = age;
      super();
      Product.$init$(this);
   }
}

case class 和 class 的一些区别:

  1. case class 在初始化的时候,不用 new,而普通类初始化时必须要 new。
  2. case class 重写了 toString 方法。 默认实现了 equals 和 hashCode
  3. case class 实现了序列化接口 with Serializable
  4. case class 支持模式匹配(最重要的特征),所有 case class 必须要有参数列表
  5. 有参数用 case class,无参用 case object

继承和多态

基本语法
class 子类名 extends 父类名 { 类体 }
(1)子类继承父类的属性和方法
(2)scala 是单继承
案例实操:
(1)子类继承父类的属性和方法
(2)继承的调用顺序:父类构造器->子类构造器

class Person(nameParam: String) {
 var name = nameParam
 var age: Int = _
 def this(nameParam: String, ageParam: Int) {
 this(nameParam)
 this.age = ageParam
 println("父类辅助构造器")
 }
 println("父类主构造器")
}
class Emp(nameParam: String, ageParam: Int) extends 
Person(nameParam, ageParam) {
 var empNo: Int = _
 def this(nameParam: String, ageParam: Int, empNoParam: Int) {
 this(nameParam, ageParam)
 this.empNo = empNoParam
 println("子类的辅助构造器")
 }
  println("子类主构造器")
}
object Test {
 def main(args: Array[String]): Unit = {
 new Emp("z3", 11,1001)
 }
}
内容来源于网络如有侵权请私信删除

文章来源: 博客园

原文链接: https://www.cnblogs.com/paopaoT/p/17487661.html

你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!