Scala语言基础(四)面向对象(一)定义类、定义构造器

mac2026-08-30  10

一、面向对象

重要的两个概念 类:相同的事物组成的一个类或裙(抽象概念:描述一类相同的事物) 对象:一个类或群体里的单个实体 面向对象的四大特征 抽象,封装,继承,多态 构建实例对象的五种方法: 1,调用构造器(公开) 2,静态工厂方法(构造器私有) 3,反射 4,克隆(object.clone()) 5,反序列化 在scala的类中,与类名相同的单例对象叫伴生对象,也就是如果我们在object Dog所在的文件内定义了一个class Dog,此时: 1,object Dog被称为class Dog的伴生对象 2, class Dog被称为object Dog的伴生类 3,类和伴生对象之间可以相互访问私有的方法和属性,private[this]修饰的除外

1. 定义类

定义类的时候,把伴生类和伴生对象放到一个文件中如果一个其他类在当前文件中使用一次,可以定义在这个文件中如果其他类被多次使用,最好定义到一个独立的文件中 //伴生类 class Student{ /** * 1,在scala中定义的属性都需要初始化 * 2,使用val修饰的属性,具有getter方法不具有setter方法 * 3,var修饰的属性具有getter和setter方法 * 4,private修饰的变量表示私有,除了自己以外,任何组件不能访问 * 但是和当前这个类同名的object组件(对应的伴生对象)中可以访问 * private修饰的属性,除了自己和自己的伴生对象可以访问,其他都不能访问 * 5,private[this]修饰的属性,只有自己访问,伴生对象也不能访问 * */ val id = 9527 var name = "唐伯虎" private var age = 18 private[this] var salary = 400000 println(age)//直接在类中就可以打印,Java中要在代码块中,这是因为scala中,由于构造方法和类名在一起,所以类体也是构造方法体,初始化构造方法时,自然会执行该代码 } /** * 如果要执行某个代码测试,就需要一个main方法组件,而且该方法必须在object中,不能放在class中,这是因为main方法相当于java中的main方法,是静态的,而scala的object相当于java中的静态类 * 在scala的一个代码文件中,可以同时定义多个类,而且这多个类可以都是public的那么其实如果没有使用任何修饰,那么这个类就是public的 * Java中多个类,则只有一个是public的 * class和object是互为伴生关系,class是伴生类,object是伴生对象 */ //伴生方法 object Student{ def main(args: Array[String]): Unit = { val student = new Student() println(student.id) } }

获取类的信息

object ClassInfo { def main(args: Array[String]): Unit = { //Scala如果想要获取类的信息,需要采用特殊的方法:classOf[类型] //classof能直接使用,因为scala.Predef伴生对象是默认导入到当前开发环境中 val userClass:Class[User] = classOf[User] println(userClass.getInterfaces) //可以使用type关键字给类起别名 type user2 = User val user3 = new user2 val user: Object = new User //判断类型 val bool: Boolean = user.isInstanceOf[user2] //转换类型 if(bool){ val user1:User = user.asInstanceOf[User] } } } class User { }

2. 定义构造器

定义无参构造器

/** * 1, 在定义一个scala的类使,如果这个类名后面没跟() * 就认为这个类有一个主构造器 类型() 但是()也可以省略 * scala中的主构造器类似于java中的无参构造器 * 2, 主构造器:直接写在类名后面的()就是 * */ class Student(){ val id = 9527 var name = "tbh" println("hello scala") } object Student{ def main(args: Array[String]): Unit = { val student = new Student() println(student.id,student.name) } }

定义有参构造器

//1.如果有参构造中的参数使用var或val修饰,默认是public的,相当于定义了一个成员变量 //2.如果属性不使用var或val修饰,就相当于是private[this] val修饰的属性 class Student(val id:Int, var name:String, age:Int){ println("hello scala") } object Student{ def main(args: Array[String]): Unit = { val student = new Student(9527,"thb",18) println(student.id,student.name) } }

私有主构造器

/** *构造器参数可以不带val或var * 不带val或var的参数至少被一个方法使用,就会被提升为字段 * 在类名后面加private和private[this]就变成私有的,相当于禁用了主构造器 * 如果一个类的主构造器被private[this]修饰,即使是伴生对象也不能访问了 * 这个时候就需要定义辅助构造器,有以下几个要点 * 1,使用def定义 * 2,方法的名称必须是this * */ class Student private(val id:Int, var name:String, age:Int){ def myAge = println(age) } object Student{ def main(args: Array[String]): Unit = { val student = new Student(9527,"thb",18) println(student.id,student.name) println(student.myAge)//调用myAge只返回空值在够造对象时就已经使用了该方法,是不能使用student.age访问age的 } }

辅助构造器

/** * 在类名后面加private和private[this]就变成私有的,相当于禁用了主构造器 * 如果一个类的主构造器被private[this]修饰,即使是伴生对象也不能访问了 * 这个时候就需要定义辅助构造器,有以下几个要点 * 1,使用def定义 * 2,方法的名称必须是this * 3,辅助构造器中的参数列表一般来说,都要包括主构造器中的参数列表 * 4,辅助构造器的{}中的第一句代码都要以其它的构造器(其他的辅助构造器或主构造器开头) * 5,里面的参数不能有修饰符 */ class Student private[this](val id:Int, var name:String){ def this(id:Int, name:String, age:Int) = { //调用了主构造器 this(id,name)//必须以调用主构造器或其他构造器开头,前面不能有其他代码 } def this(id:Int, name:String, age:Int, xx:Int) = { //调用了辅助构造器 this(id,name,age)//必须以调用主构造器或其他构造器开头,前面不能有其他代码 } } object Student{ def main(args: Array[String]): Unit = { val student = new Student(9527,"thb",18) println(student.id) } } object ParentConstructor { def main(args: Array[String]): Unit = { val b: A = new B("zhangsan",20,"Beijing") // 一次打印 A的主构造的方法 B的主构造方法 B的辅助构造方法 } } class A() { println("A的主构造的方法") } class B(b: String) extends A { println("B的主构造方法") def this(name: String,age:Int,address:String) { this(address) // 辅助构造方法必须在第一行引用 主构造方法或辅助构造方法 println("B的辅助构造方法") } } //如果父类主构造方法有参数,那么构建对象时必须显式的传递参数 //可以在继承的父类后面增加小括号,传递参数,等同于调用父类构造方法 class C() extends B("d"){ }

总结: a. 带参构造器参数有4种类型 1,由var或val修饰,自动成为成员属性 2,没有var或val修饰,相当于private[this] val修饰 3,由private var/val修饰 4,由private[this] val 修饰 b. 主构造方法 1,与类名交互在一起 2,主构造器运行,类名后面大括号里面的代码都会运行 c. 辅助构造器 1,名字必须是this 2,必须以调用柱构造器或其他辅助构造器方法开始 3,里面的属性不能写修饰符

3. 类的方法及属性

// 类的方法,所谓的方法,其实就是类中声明的函数,所以声明方法和函数是一样的,调用上有区别 object Class_Method { def main(args: Array[String]): Unit = { val aaa = new BBB() } } // 类可以声明为抽象的 abstract class AAA { val i = 10 var age = "xxxx" var name: String = _ //scala中属性也可以重写,因为属性可以抽象 //属性只声明,而没有初始化,那么就是抽象属性(scala中的属性必须显性初始化) //抽象属性在编译为class文件时,不产生属性,但是产生一个getter方法 var sex: String //声明抽象方法,方法只有声明没有实现,不需要abstract关键字 def test() } class BBB extends AAA { // IDEA中重写方法的快捷键:ctrl+o(override) 实现方法快捷键:ctrl+i(implement) //scala中如果子类重写父类的方法或属性(不是抽象的),必须要加关键字override //实现抽象方法或属性override关键字可加可不加 override val i = 20 //scala中不可以重写var修饰的属性 override var age ="YYYY" override var sex: String = _ override def test(): Unit = { println("hello world") } }
最新回复(0)