Scala系列-3、scala中的类和对象有哪些?

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

传送门:大数据系列文章目录
在这里插入图片描述

如何使用IDEA创建scala项目

创建普通的scala项目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
接下来, 即可创建包结构, 编写scala代码

创建scala的maven项目

  1. 创建一个maven项目, 添加如下依赖
    <properties>
        <project.build.source.Encoding>UTF-8</project.build.source.Encoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>2.12.11</version>
        </dependency>

    </dependencies>

    <build>
        <sourceDirectory>src/main/scala</sourceDirectory>
        <testSourceDirectory>src/test/scala</testSourceDirectory>
        <plugins>
            <!-- Scala编译插件-->
            <plugin>
                <groupId>org.scala-tools</groupId>
                <artifactId>maven-scala-plugin</artifactId>
                <version>2.15.2</version>
                <executions>
                    <execution>
                        <id>scala-compile-first</id>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                        <configuration>
                            <includes>
                                <include>**/*.scala</include>
                            </includes>
                        </configuration>
                    </execution>
                    <execution>
                        <id>scala-test-compile</id>
                        <goals>
                            <goal>testCompile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <!-- maven编译插件-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.7.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
  1. 分别在src/main下构建scala目录(创建完文件夹是白色的,往下看)

在这里插入图片描述

  1. 点击刷新, 将scala目录变更为source目录

在这里插入图片描述

刷新完的效果:
在这里插入图片描述

  1. 编写代码进行书写即可

scala的中普通类

创建类也是使用class的关键词来构建的
在这里插入图片描述
创建普通类:

package com.lwh

/**
 * @author lwh
 * @date 2022/11/17
 * @description
 **/
class Person {
  // 注意: 在普通类中定义成员变量的时候, 如果使用val定义, 必须要进行赋值,
  //   如果使用 var定义, 可以使用 _ 替代 , 此时赋上默认值
  //  在类中不存在 Public  scala认为 只要不带权限修饰符的都是 public , 支持的权限符号:  private || protected
  //private  val name:String  = "张三"
  val name:String  = "张三"
  var age:Int = 20
  var birthday:String = _


  def eat(name:String): Unit = {
    println(name + "饿了.....")
  }

}

定义main方法: main必须放置在Object类

package com.lwh

/**
 * @author lwh
 * @date 2022/11/17
 * @description
 **/
object MainTest {
  def main(args: Array[String]): Unit = {
    //1. 创建对象:
    val perosn1:Person = new Person()
    // 说明 如果 无参数, () 是可以省略的
    val perosn2:Person = new Person

    // 获取成员变量
    println(perosn1.name)
    println(perosn1.age)
    println(perosn1.birthday)
    // 设置成员变量: 只能设置被 var修饰

    // perosn1.name = "李四"   name是被 val修饰 编译直接报错
    perosn1.age = 30
    perosn1.birthday = "2020-10-10"

    println(perosn1.age)
    println(perosn1.birthday)

    // 调用方法:

    perosn1.eat("老王")
  }

}

构造器:

在scala中普通类也是存在构造方法的, 默认情况下都是会有一个无参构造方法, 在scala即使有了有参构造, 无参依然存在的

在scala中将构造分为两大类:

  • 主构造: 直接放置在类的后面, 通过括号来执行构造器的参数即可

  • 主构造器的格式:

class 类名(var/val 参数名:类型 = 默认值, var/val 参数名:类型 = 默认值){
    // 构造代码块
}

说明: 
	- 主构造器的参数列表是直接定义在类名后面,添加了val/var表示直接通过主构造器定义成员变量
	- 构造器参数列表可以指定默认值
	- 创建实例,调用构造器可以指定字段进行初始化
	- 整个class中除了字段定义和方法定义的代码都是构造代码

  • 相关的操作

在这里插入图片描述

  • 辅助构造器:
  • 格式:
def this(参数名:类型, 参数名:类型) {
    // 第一行需要调用主构造器或者其他构造器
    // 构造器代码
}

 - 辅助构造器的第一行代码,必须要调用主构造器或者其他辅助构造器

在这里插入图片描述

创建对象:
	//2. 基于辅助构造器, 创建person对象
    val person3 = new Person(Array("李四"))
    println(person3.name)

    val person4 = new Person(List("王五"))
    println(person4.name)

scala的单例对象

在scala中是不支持static修饰的, 所以在普通类中创建的成员变量和成员的方法都是非静态的, 那么如果我们想构建静态的变量或者静态的方法就得需要scala提供的单例对象

在单例对象中定义的成员变量和成员方法都是静态的, 可以直接通过类名调成员即可。
如何构建单例对象: 与构建普通类类似的, 只是将 class修改为Object即可

相关的操作:

  • 创建单例对象:
package com.lwh

/**
 * @author lwh
 * @date 2022/11/17
 * @description
 **/
object Student {
  val name: String = "李四同学"
  var age: Int = 20
  val address: String = "北京"

  def study(name: String): Unit = {
    println(name + "说:我要努力好好学习scala")
  }
}

  • 使用单例对象
package com.lwh

/**
 * @author lwh
 * @date 2022/11/17
 * @description
 **/
object StudentTest {

  def main(args: Array[String]): Unit = {
    println(Student.address)
    Student.study("老王")
  }
}

单例对象一般被用于构建工具类:

需求

  • 编写一个DateUtil工具类专门用来格式化日期时间
  • 定义一个方法,用于将日期(Date)转换为年月日字符串,例如:2030-10-05
package com.lwh

import java.text.SimpleDateFormat
import java.util.Date

/**
 * @author lwh
 * @date 2022/11/17
 * @description
 **/
object DateUtil {

  private val dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")

  def format(date: Date): String = {
    dateFormat.format(date)
  }
}

使用工具类:

package com.lwh

import java.util.Date

/**
 * @author lwh
 * @date 2022/11/17
 * @description
 **/
object DateUtilTest {

  def main(args: Array[String]): Unit = {
    val dateStr: String = DateUtil.format(new Date)
    println(dateStr)
  }
}

main方法

在java中, 执行代码必须有主入口main , 同样对应scala也是需要的, 在java中main方法是静态的方法, 在scala中如果要使用main方法, 那么必须将其定义在单例对象才可以

object Main5 {
  def main(args:Array[String]) = {
    println("hello, scala")
  }
}

除了直接显现使用main方法, scala还支持其通过继承一个特质来完成main方法的编写

object 单例对象名 extends App {
    // 方法体
}
package com.lwh

import java.util.Date

/**
 * @author lwh
 * @date 2022/11/17
 * @description
 **/
object DateUtilAppTest extends App {
  private val dateStr: String = DateUtil.format(new Date)
  println(dateStr)

}

scala的伴生对象

伴生对象主要解决什么问题: 一个类中既有静态的成员 又有非静态的成员, 此时在scala中采用伴生对象来解决

使用伴生对象的操作条件:

一个class和object具有同样的名字。这个object称为伴生对象,这个class称为伴生类

  • 伴生对象必须要和伴生类一样的名字
  • 伴生对象和伴生类在同一个scala源文件中
  • 伴生对象和伴生类可以互相访问private属性

示例
示例说明

  • 编写一个CustomerService类,有一个save方法,打印
服务类名称:保存客户
  • 编写一个CustomerService伴生对象,定义一个私有变量,用于保存服务类名称

  • 创建CustomerService对象,调用save方法1

package com.lwh

/**
 * @author lwh
 * @date 2022/11/17
 * @description
 **/
//伴生类
class CustomerService {

  // 在伴生类定义变量 或者 方法 都是非静态的
  def save() = {
    println(CustomerService.serviceName + "保存客户")
  }

}

//伴生对象
object CustomerService {

  // 在伴生对象中定义的变量或者方法 都是静态的
  private val serviceName = "业务端"
}
  • 操作伴生对象
package com.lwh

/**
 * @author lwh
 * @date 2022/11/17
 * @description
 **/
object CustomerServiceTest extends App {

  private val service = new CustomerService
  service.save()
}

目前存在一个问题: 伴生对象在创建的时候, 可以不使用new的方式, 但是经过测试发现, 无法实施 如何解决呢?

解决方法: 需要在伴生对象中重写 apply的方法, 那么这样的化,就可以直接不采用new的方式来构建对象了

package com.lwh

/**
 * @author lwh
 * @date 2022/11/17
 * @description
 **/
//伴生类
class CustomerService {

  // 在伴生类定义变量 或者 方法 都是非静态的
  def save() = {
    println(CustomerService.serviceName + "保存客户")
  }

}

//伴生对象
object CustomerService {

//  特别注意:
//    在重写apply方法适合, 如果空参, 一定带上 括号, IDEA快捷方式可能没有生产正确
  def apply(): CustomerService = new CustomerService()

  // 在伴生对象中定义的变量或者方法 都是静态的
  private val serviceName = "业务端"
}

注意: 一旦在成员变量的添加 添加 private[this] 仅能在当前类中使用, 其他的类就无法使用, 即使是伴生类也不行

scala的继承

scala的继承基本与java的继承是一致的, 也是通过extends方式来继承, 同时也是单继承的操作, 在scala中我们既可以使用普通类来继承父类, 也可以使用单例对象来继承父类

在继承后, 相当于将父类的所有的成员变量和成员方法都继承了过来

相关的操作:

  • 创建一个父类
package com.lwh

/**
 * @author lwh
 * @date 2022/11/17
 * @description
 **/
class Animal(var eatFood:String = "吃东西") {

  def eat(name:String) = {
    println(name + ":" + eatFood)
  }
}

  • 普通类继承父类
package com.lwh

/**
 * @author lwh
 * @date 2022/11/17
 * @description
 **/
class Dog extends Animal {

  // override 表示是重写方法
  // super  调用父类的方法
  override def eat(name: String): Unit = {
    // 先调用父类的方法
    super.eat(name)

    println("狗吃骨头.....")
  }

  def work() = {
    println("狗能看门")
  }
}

  • 单例对象继承父类
package com.lwh

/**
 * @author lwh
 * @date 2022/11/17
 * @description
 **/
object Cat extends Animal {

  override def eat(name: String): Unit = {
    super.eat(name)
    println("猫吃鱼......")
  }
}

  • 使用操作
package com.lwh

/**
 * @author lwh
 * @date 2022/11/17
 * @description
 **/
object AnimalTest extends App {

  private val dog = new Dog
  dog.eat("哈士奇")
  dog.work()

  println(Cat.eatFood)
  Cat.eat("波斯猫")
}

scala中抽象类

scla的抽象类的操作与java是一致的

  • 定义抽象类
package com.lwh

/**
 * @author lwh
 * @date 2022/11/17
 * @description
 **/
abstract class AnimalAbstract {
  // 抽象的成员变量
  var name:String

  val age:Int

  val address:String = "森林里"

  // 抽象的方法:
  def eat()

  def run() = {
    println("动物都是可以跑的.....")
  }
}

  • 实现抽象类
package com.lwh

/**
 * @author lwh
 * @date 2022/11/17
 * @description
 **/
class Tiger extends AnimalAbstract {
  override val age: Int = 10
  override var name: String = "东北虎"

  override def eat(): Unit = {
    println("老虎喜欢吃肉")
  }
}

  • 操作下
package com.lwh

/**
 * @author lwh
 * @date 2022/11/17
 * @description
 **/
object AnimalAbstractTest extends App {
  private val tiger = new Tiger
  tiger.run()
  tiger.eat()

  println(tiger.name +"  "+tiger.age +"  "+tiger.address)
}

scala中匿名内部类

package com.lwh

/**
 * @author lwh
 * @date 2022/11/17
 * @description
 **/
object AnimalInnerTest extends App {

  // 假设目前使用cat的操作, 此操作只需要使用一次, 此时可以采用匿名内部类来实现, 因为如果直接构建一个实现类, 有点大材小用

  val cat = new AnimalAbstract {
    override var name: String = "加菲猫"
    override val age: Int = 5

    override def eat(): Unit = {

      println("猫吃鱼..........")

    }

    override def run(): Unit = {
      super.run()

      println("猫在追耗子的时候, 可以跑起来")
    }
  }

  cat.eat()
  cat.run()

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术武器库

一句真诚的谢谢,胜过千言万语

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值