六、Scala的类和对象

六、Scala的类和对象,第1张

六、Scala的类和对象

Scala的类和对象
  • 1.类和对象
    • 1.1 相关概念
    • 1.2 创建类和对象
    • 1.3 简写方式
  • 2.定义和访问成员变量
  • 3. 使用下划线初始化成员变量
  • 4. 定义和访问成员方法
  • 5. 访问修饰符
  • 6. 类的构造器
    • 6.1 主构造器
    • 6.2 辅助构造器
  • 7. 单例对象
    • 7.1 定义单例对象
    • 7.2 在单例对象中定义方法
  • 8. main方法
    • 8.1 定义main方法
    • 8.2 继承App特质
  • 9.伴生对象
    • 9.1 定义伴生对象
    • 9.2 private[this]访问权限
    • 9.3 apply方法
  • 10. 案例:定义工具类


1.类和对象 1.1 相关概念

面向对象:一种编程思想,是基于面向过程的,强调的是以对象为基础完成各种 *** 作
类:属性和行为的集合,是一个抽象的概念
属性/成员变量:名词,用来描述事物的外在特征
行为/成员方法:动词,表示事物能够做什么
对象:类的具体实现
面向对象的三大特征:封装,继承,多态

1.2 创建类和对象

用class来创建类,用new来创建对象

在IDEA中创建项目,并创建一个object类(main方法必须放在Object中):




实际开发中,实体类和测试类会分开写:

后续为了方便,会合并到一起:

1.3 简写方式

用法:

  • 如果类是空的,没有任何成员,可以省略{}
  • 如果构造器的参数为空,可以省略()

示例:

object ClassDemo {
	
	//1.创建Person类
	class Person

	//2.定义main函数,它是程序的主入口
	def main(args: Array[String]): Unit = {
		//3.创建Person类型的对象
		val p = new Person
		//4.将对象打印到控制台上
		println(p)
	}
}
2.定义和访问成员变量

用法:

  • 在类中使用var/val来定义成员变量
  • 对象可以通过对象名.的方式来访问成员变量

示例:

object ClassDemo {
	
	//1.创建Person类
	class Person{
		//2.定义名字和年龄字段
		//方式一:普通写法
		//val name:String = ""
		//方式二:采用类型推断实现
		val name = ""
		val age = 0
	}

	//3.定义main函数,它是程序的主入口
	def main(args: Array[String]): Unit = {
		//4.创建Person类型的对象
		val p = new Person
		//5.给对象的成员变量赋值
		p.name = "mike"
		p.age = 23
		//6.打印属性值
		println(p.name, p.age)
	}
}
//(mike, 23)
3. 使用下划线初始化成员变量

Scala有一个更简洁的初始化成员变量的方式。

用法:

  • 在定义var类型的成员变量时,可以使用_来初始化成员变量
    • String => null
    • Int => 0
    • Boolean => false
    • Double => 0.0
  • val类型的成员变量,则需要自己手动初始化

示例:

object ClassDemo {
	
	//1.创建Person类
	class Person{
		//2.定义名字和年龄字段
		//方式一:普通写法
		//val name:String = ""
		//方式二:采用类型推断实现
		//val name = ""
		//方式三:采用下划线来初始化成员变量值
		//val name:String = _  //报错,因为这种下划线方式只针对var类型的变量
		var name:String = _
		var age:Int = _
	}

	//3.定义main函数,它是程序的主入口
	def main(args: Array[String]): Unit = {
		//4.创建Person类型的对象
		val p = new Person
		//5.给对象的成员变量赋值
		p.name = "mike"
		p.age = 23
		//6.打印属性值
		println(p.name, p.age)
	}
}
//(mike, 23)
4. 定义和访问成员方法

Scala类中,也是使用def来定义成员方法的。
示例:

object ClassDemo {
	
	//1.创建Customer类
	class Customer{
		//2.定义成员变量(姓名和性别)
		var name:String = _
		var sex = ""

		//定义成员方法printHello()
		
		//简化版
		def printHello(msg:String) : Unit = println(msg)
	}

	//3.定义main函数,它是程序的主入口
	def main(args: Array[String]): Unit = {
		//4.创建Customer类型的对象
		val c = new Customer
		//5.给对象的成员变量赋值
		c.name = "mike"
		c.sex = "male"
		//6.打印属性值
		println(c.name, c.age)
		//7.调用成员方法
		c.printHello("hi")
	}
}
//(mike, male)
//hi
5. 访问修饰符

和Java一样,Scala也可以通过访问修饰符,来控制成员变量和成员方法是否可以被外界访问。

定义:

  • 可以在成员前面添加private/protected关键字来控制成员的可见性
  • 在Scala中,没有public关键字,任何没有被标为private或protected的成员都是公共的(因此,Scala的权限修饰符只有四种:private, private[this], protected, 默认)

示例:

object ClassDemo {
	
	//1.创建Person类
	class Person{
		//2.定义私有的成员变量
		private var name:String = _
		private var age = 0
		
		//3.定义成员方法
		def getName():String = name
		def setName(name:String):Unit = this.name = name
		def getAge():Int = age
		def setAge(age:Int):Unit = this.age = age
		private def sayHello():Unit = println("hi")
	}

	//4.定义main函数,它是程序的主入口
	def main(args: Array[String]): Unit = {
		//5.创建Person类型的对象
		val p = new Person
		//6.给对象的成员变量赋值
		//p.name = "mike" //报错,因为被private修饰的内容只能在本类中被直接访问
		p.setName("mike")
		p.setAge(23)
		//7.打印成员变量值
		println(p.getName(), p.getAge())
		//8.尝试调用Person类中的私有成员方法
		//p.sayHello() //报错,因为被private修饰的内容只能在本类中被直接访问
	}
}
//(mike, 23)
6. 类的构造器 6.1 主构造器

语法:

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

注意:

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

示例:

object ClassDemo {
	
	//1.创建Person类,在主构造器中指定:姓名、年龄
	class Person(val name: String = "mike", val age: Int = 23){
		//2.在主构造器中输出“调用主构造器”
		println("调用主构造器了!')
	}

	//3.定义main函数,它是程序的主入口
	def main(args: Array[String]): Unit = {
		//4.创建空对象,并打印属性值
		val p1 = new Person()
		println(s"p1: ${p1.name}, ${p1.age}")
		//5.创建全参对象,并打印属性
		val p2 = new Person("lee", 24)
		println(s"p2: ${p2.name}, ${p2.age}")
		//6.创建对象,仅指定年龄,并打印属性值
		val p3 = new Person(age = 30)
		println(s"p3: ${p3.name}, ${p3.age}")
	}
}
//调用主构造器了!
//(mike, 23)
//调用主构造器了!
//(lee, 24)
//调用主构造器了!
//(mike, 30)
6.2 辅助构造器

辅助构造器的目的是让我们有多些创建对象的形式。

语法:

  • 定义辅助构造器与定义方法一样,也使用def关键字
  • 辅助构造器的默认名字都是this,且不能修改
def this(参数名:类型,参数名:类型) {
	//第一行需要调用主构造器或者其他构造器
	//构造器代码
}

示例:

object ClassDemo {
	
	//1.创建Customer类,在主构造器中指定:姓名、地址
	class Customer(val name: String, val address: String) {
		//2.定义辅助构造器,接收一个数组类型的参数
		def this(arr:Array[String]) {
			//细节:辅助构造器第一行代码必须访问主构造器或其他的辅助构造器
			this(arr(0), arr(1))
		}
	}

	//3.定义main函数,它是程序的主入口
	def main(args: Array[String]): Unit = {
		//4.通过辅助构造器创建Customer类型的对象
		val c = new Customer(Array("mike", "beijing"))
		//val c2 = new Customer("lee", "shanghai")  //通过主构造器创建对象
		//5.打印属性值
		println(c.name, c.address)
	}
}
//(mike, beijing)
7. 单例对象

Scala中是没有static关键字的,要想定义类似于Java中的static变量、static方法,就要用到Scala中的单例对象,即object。

7.1 定义单例对象

单例对象表示全局仅有一个对象,也叫孤立对象。定义单例对象和定义类很像,就是把class换成object。
格式:

object 单例对象名{ }  

注意:

  • 在object中定义的成员变量类似于Java中的静态变量,在内存中都只有一个对象
  • 在单例对象中,可以直接使用单例对象名.的形式调用成员

示例:

object ClassDemo {
	
	//1.定义单例对象Dog
	object Dog {
		//2.定义一个变量,用来保存狗腿的数量
		val leg_num = 4
	}

	//3.定义main函数,它是程序的主入口
	def main(args: Array[String]): Unit = {
		//4.直接打印狗腿数量
		println(Dog.leg_num)
	}
}
//4
7.2 在单例对象中定义方法

在单例对象中定义的成员方法类似于Java中的静态方法。

示例:

object ClassDemo {
	
	//1.定义单例对象PrintUtil
	object PrintUtil {
		//2.定义一个方法,用来打印分割线
		def printSpliter() = println("-" * 15)
	}

	//3.定义main函数,它是程序的主入口
	def main(args: Array[String]): Unit = {
		//4.调用单例对象中的成员方法,打印分割线
		PrintUtil.printSpliter()
	}
}
//---------------
8. main方法

Scala程序中,如果要运行一个程序,必须有一个main方法。在Java中main方法是静态的,而在Scala中没有静态方法。所以,Scala中这个main方法必须放在一个单例对象中。

8.1 定义main方法
def main(args:Array[String]):Unit = {
	//方法体
}

示例:

def main(args:Array[String]):Unit = {
	println("hi")
}
//hi
8.2 继承App特质

创建一个object,继承App特质(Trait),然后将需要编写在main方法中的代码,写在object的构造方法体内。

object 单例对象名 extends App {
	//方法体
}

示例:

object ClassDemo extends App {
	println("hi")
}
//hi
9.伴生对象

在 Java 中有一些类,会同时有静态内容和非静态内容,在 Scala 中想要实现类似效果可以使用伴生对象来实现。

9.1 定义伴生对象

一个 class 和 object 具有相同的名字,这个 object 被称为伴生对象,这个 class 被称为半生类。
伴生对象和半生类可以互相访问 private 属性,必须写在同一个scala源文件。

示例:

object ClassDemo {
	
	//1.定义伴生类Generals
	class Generals { //里面写的内容都是非静态的
		//2.定义toWar()方法,表示打仗
		def toWar() = println(s"武将拿着${Generals.armsName}武器,上阵杀敌")
	}

	//3.定义伴生对象
	object Generals { //里面写的内容都是静态的
		//4.定义一个私有的成员变量,用来保存武器的名称
		private val armsName = "大刀" 
	}

	//5.定义main函数,它是程序的主入口
	def main(args: Array[String]): Unit = {
		//6.创建伴生类的对象
		val c = new Generals
		//7.调用toWar()方法
		c.toWar()
	}
}
//武将拿着大刀武器,上阵杀敌
9.2 private[this]访问权限

如果某个成员变量权限为 private[this],表示只能在当前类访问,伴生对象也不能直接访问。

示例:

object ClassDemo {
	
	//1.定义伴生类Person,并在其中定义一个name字段
	//class Person(private[this] var name:String) { //这样写会报错
	class Person(private var name:String) { //里面写的内容都是非静态的
		
	}

	//2.定义Person类的伴生对象
	object Person { //里面写的内容都是静态的
		//3.定义一个printPerson()方法,用来打印某个Person对象的属性值
		def printPerson(p:Person) = println(p.name)
	}

	//4.定义main函数,它是程序的主入口
	def main(args: Array[String]): Unit = {
		//5.调用伴生对象中的printPerson()方法,尝试是否可以访问private[this]修饰的内容
		val p = new Person("mike")
		Person.printPerson(p)
	}
}
//mike
9.3 apply方法

Scala中,支持创建对象的时候不用new这个关键字(免new),实现需要通过对伴生对象的apply方法来实现。

定义apply方法的格式:

object 伴生对象名 {
	def apply(参数名:参数类型, (参数名:参数类型...) = new 类(...)
}

创建对象:

val 对象名 = 伴生对象名(参数1,参数2,...)

示例:

object ClassDemo {
	
	//1.定义伴生类Person, 属性:姓名、年龄
	class Person(var name:String = "", var age:Int = 0) {}

	//2.定义Person类的伴生对象
	object Person {
		//3.定义一个apply()方法,用来实现创建Perosn对象时候免new
		//apply()方法,Scala SDK会自动调用
		def apply(name:String, age:Int) = new Person(name, age)
	}

	//4.定义main函数,它是程序的主入口
	def main(args: Array[String]): Unit = {
		//5.创建Person类型的对象
		val p = Person("mike", 23)
		//6.打印对象的属性值
		println(p.name, p.age)
	}
}
//(mike, 23)
10. 案例:定义工具类

Scala中工具类的概念和Java中是一样的,都是

  • 构造方法全部私有化,目的是不让外界通过构造方法来创建工具类的对象
  • 成员全部是静态化,意味着外界可以通过"类名."的形式来访问工具类中的内容

综上所述,Scala中只有object单例对象满足上述要求

示例:

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

object ClassDemo {
	//1.定义工具类DataUtils
	object DataUtils {
		//2.细节:定义一个SimpleDateFormat类型的对象
		var sdf:SimpleDateFormat = null
		//3.定义data2String()方法,用来将日期对象转换成其对应的字符串
		def data2String(date: Date, template:String) = {
			sdf = new SimpleDateFormat(template)
			sdf.format(date)
		}
		//4.定义string2Date()方法,用来将字符串形式的日期转换成其对应的字符串
		def string2Date(dateString: String, template:String) = {
			sdf = new SimpleDateFormat(template)
			sdf.parse(dateString)
	}

	//5.定义main函数,它是程序的主入口
	def main(args: Array[String]): Unit = {
		//6.测试date2String()方法
		println(DateUtils.date2String(new Date(), "HH:mm:ss"))
		//7.测试string2Date()方法
		println(DateUtils.string2Date("1234年5月21日", "yyyy年MM月dd日"))
	}
}
//20:12:46
//Tue May 21 00:00:00 CST 1314

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4668302.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-06
下一篇 2022-11-06

发表评论

登录后才能评论

评论列表(0条)

保存