目录

抽象类

抽象属性/方法

抽象类的继承和重写

匿名子类

单例对象(伴生对象)

单例对象语法

特质

特质和抽象类的区别

特质声明

特质基础语法


抽象类

在scala中,抽象类是用abstract关键字修饰的类,他的核心特点是:

        1.可以包含未实现的抽象成员(抽象方法,抽象字段),也可以包含已经实现的具体成员

        2.不能直接实例化(无法new创建对象),必须通过子类继承并实现所有抽象成员后才能实例化

简单类比:抽象类就像一份"半成品设计图",规定了子类必须具备的功能(抽象成员),同时也提供了子类可以直接使用的通用功能(具体成员)

抽象属性/方法

基本语法:

        1.定义抽象类:abstract class Person{}  通过abstract关键字标记抽象类

        2.定义抽象属性: val|var name:String    一个属性没有初始化,就是抽象属性

        3.定义抽象方法:def hello():String         只是声明而没有实现的方法,就是抽象方法

abstract class Person{
    val name:String    // 抽象属性
    def hello():Unit   // 抽象方法
}
// 抽象类不可以直接调用,必须由子类来继承使用
class Teacher extends Person {
    val name:String = "teacher"
    def hello():Unit = {
        println("hello teacher")
    }
}

抽象类的继承和重写

1.如果父类为抽象类,那么子类需要将抽象的属性和方法实现,否则子类也需声明

为抽象类
2.重写非抽象方法需要用 override 修饰,重写抽象方法则可以不加 override
3.子类中调用父类的方法使用 super 关键字
4.子类对抽象属性进行实现,父类抽象属性可以用 var 修饰;
   子类对非抽象属性重写,父类非抽象属性只支持 val 类型,而不支持 var
   因为 var 修饰的为可变变量,子类继承之后就可以直接使用,没有必要重写
def main(args:Array[String]):Unit = {
    val student = new Student
    student.eat()
    student.sleep()
    
}

// 定义一个抽象类
abstract class Person{
    //非抽象属性
    val name:String = "person"

    // 抽象属性
    var age:Int

    // 非抽象方法
    def eat():Unit = {
        println("person eat")
    }

    // 抽象方法
    def sleep():Unit
}

// 定义具体实现子类
class Student extents Person{
    // 重写抽象属性和抽象方法
    var age:Int = 18
    
    def sleep():Unit = {  
        println("student sleep")
    }
    
    // 重写非抽象属性和方法,必须加上override
    override val name:String = "student"
    override def eat():Unit = {
        super.eat()  
        println("student eat")
    }
}

匿名子类

在 Scala 中,匿名子类 是指:不单独定义一个具名的子类(比如class Cat extends Animal),而是在创建对象时,直接通过 new 父类/特质 { ... } 的方式,一次性 实现父类(通常是抽象类或特质)的抽象成员,并直接生成该子类的实例。

简单类比:匿名子类就像 “临时定制” 的子类 —— 你不需要给它起名字,只用这一次,用完就丢,适合快速创建一个仅需单次使用的子类实例。

def main(args:Array[String]):Unit = {
    val person = new Person{
        override var name:String = "alice"
        override def eat():Unit = {
            println("person eat")
        }
    }
    println(person.name)
    person.eat()
}
abstract class Person {
    var name:String
    def eat():Unit
}

单例对象(伴生对象)

在 Scala 中,伴生对象 是指:

  • 与一个类(称为 “伴生类”)同名的 object(单例对象);
  • 两者必须定义在同一个源文件中;
  • 伴生对象和伴生类可以互相访问对方的私有成员(私有字段、私有方法),这是它最核心的特性;
  • 伴生对象属于 “静态上下文”(类似 Java 的静态方法 / 字段),而伴生类是实例上下文。

单例对象语法

基本语法:

        object Person{

                val country:String = "china"

        }

单例对象采用 object 关键字声明
单例对象对应的类称之为 伴生类 ,伴生对象的名称应该和伴生类名一致。
单例对象中的属性和方法都可以通过伴生对象名(类名)直接调用访问
// 半生对象
object Person{
    val school:String = "hbcsjs"

}
// 定义类
class Person(val name:String,val age:Int){
    def printInfo(){
        println(s"person:name = ${name},age = ${age},school=${Person.school}")   
    }

}
def main(args:Array[String]):Unit = {
    val person = new Person("alice" , 18)
    person.printInfo()

}

特质

特质和抽象类的区别

1. 优先使用特质。一个类扩展多个特质是很方便的,但却只能扩展一个抽象类。
2. 如果你需要构造函数参数,使用抽象类。因为抽象类可以定义 带参数 的构造函数,
而特质不行(有无参构造)。

特质声明

        Scala 语言中,采用特质 trait (特征)来代替接口的概念 ,也就是说,多个类具有相同
的特质(特征)时,就可以将这个特质(特征)独立出来,采用关键字 trait 声明。
        Scala 中的 trait 中即 可以有抽象属性和方法,也可以有具体的属性和方法 一个类可
以混入( mixin )多个特质 。这种感觉 类似于 Java 中的抽象类。
        Scala 引入 trait 特征,第一可以替代 Java 的接口,第二个也是对单继承机制的一种

特质基础语法

定义特质:

trait 特质名 {

        trait主体

}

基本语法:

没有父类 class 类名 extends 特质 1 with 特质 2 with 特质 3 …
有父类 class 类名 extends 父类 with 特质 1 with 特质 2 with 特质 3…
说明:
             类和特质的关系:使用继承的关系。
             当一个类去继承特质时,第一个连接词是 extends ,后面是 with
            如果一个类在同时继承特质和父类时,应当把父类写在 extends 后。                                                           

案例演示:

def main(args:Array[String]):Unit = {
    var student = new Students
    student.sayHello()
    student.study()
    student.dating()
    student.play()
}

// 定义一个父类
class Person1{
    val name:String = "person"
    var age:Int = 18
    def sayHello():Unit = {
        println("hello from" + name)
    }
}

// 定义一个特质
trait Young{
    // 声明抽象和非抽象属性
    var age:Int
    val name:String = "young"

    //  抽象和非抽象方法
    def play():Unit = {
        println("young people is playing")
    }  
    
    def dating():Unit
}

class Students extends Person1 with Young{
    // 重写冲突属性
    override val name:String = "student"

    // 实现(重写)抽象方法
   def dating():Unit = {
        println(s"student ${name} is dating")
    }
    
    // 创建方法
    def study():Unit = {
        println(s"student ${name} is studying")
    }
    
    // 重写父类方法
    override def sayHello():Unit = {
        // 先调用父类方法
        super.sayHello()
        println(s"hello from:student ${name}")
    }
}

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐