在之前的文章中总结了Scala面向对象模块基础的内容,接下来学习面向对象的高阶内容。
==================================================================
如何定义?
// 定义抽象类
abstract class 类名{
// 定义抽象属性 不赋初始值
val|var 变量名: 类型
// 定义抽象方法 只声明,不实现
def 方法名(): 返回值类型
}
-
如果父类为抽象类,那么子类需要将抽象的属性和方法实现,否则子类也需声明为抽象类
-
重写非抽象方法需要用
override
修饰,重写抽象方法则可以不加override
-
子类中调用父类的方法使用
super
关键字 -
子类对抽象属性进行实现,父类抽象属性可以用
var
修饰; -
子类对非抽象属性重写,父类非抽象属性只支持
val
类型,而不支持var
。因为var
修饰为可变量,子类继承后可以直接使用修改,没有必要重写。
举个栗子:
// 定义抽象类
abstract class Person{
// 定义非抽象属性
val name: String = "person"
// 抽象属性
var age: Int
// 非抽象方法
def eat(): Unit ={
println("Person eat")
}
// 抽象方法
def sleep(): Unit
}
class Student extends Person{
// 实现抽象属性和方法
var age: Int = 18
def sleep(): Unit ={
println("student sleep")
}
// 重写非抽象属性和方法
override val name: String = "Student"
override def eat(): Unit = {
super.eat()
println("Student eat")
}
}
匿名子类
和 Java 一样,可以通过包含带有定义或重写的代码块的方式创建一个匿名的子类。匿名子类只针对抽象类和接口。
举个栗子:
object Test10_AnnoymousClass {
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)
person10.eat()
}
}
abstract class Person {
var name: String
def eat():Unit
}
=========================================================================
Scala是一门完全面向对象的语言,没有静态操作。为了能够和Java语言进行交互,使用单例对象来取代static
关键字的语义,伴生类的静态声明
都可放在伴生对象中。
基本语法:
object 伴生对象名{
val country: String="China"
}
-
编译后会生成两个类,伴生对象是伴生类(类名为对应类后加$符号)的单例对象。
-
单例对象对应的类称之为伴生类,伴生对象的名称应该和伴生类名一致,必须在同一个文件中。
-
单例对象中的属性和方法都可以通过伴生对象名(类名)直接调用访问。
-
Scala 中
obj(arg)
的语句实际是在调用该对象的apply
方法,即obj.apply(arg)
。用以统一面向对象编程和函数式编程的风格。 -
Scala底层对于伴生对象的
apply
方法进行了优化,调用时可以省略方法名,直接使用单例对象的名称+调用apply方法的参数
-
当使用
new
关键字构建对象时,调用的其实是类的构造方法,当直接使用类名构建对象时,调用的其实时伴生对象的apply
方法
举个栗子:
// 伴生类
// 构造器私有化
class Student private(val name: String, val age: Int) {
def printInfo(): Unit = {
println(s"Student11: $name $age ${Student11.school}")
}
}
// 伴生对象
object Student {
// 看作静态的属性
val school: String = "清华"
// 定义类对象实例创建的方法
def newStudent(name: String,age: Int): Student11 = new Student11(name,age)
def apply(name: String, age: Int): Student11 = new Student11(name, age)
}
object Test11_Object {
def main(args: Array[String]): Unit = {
val student = Student.newStudent("alice", 12)
student.printInfo()
val student1 = Student.apply("haha", 12)
val student2 = Student("lolo", 34)
student2.printInfo()
}
}
=================================================================
如何定义特质?
trait 特质名 {
// 代码块
}
-
Scala 语言中,采用特质
trait
(特征)来代替接口的概念 -
多个类具有相同的特征时,就可以将这个特征提取出来,用继承的方式来复用
-
Scala 中的 trait 中即可以有抽象属性和方法,也可以有具体的属性和方法,一个类可以混入(
mixin
)多个特质。这种感觉类似于 Java 中的抽象类。
基本语法:
有父类 class extends baseClass with trait1 with trait2 ... {}
没有父类 class extends trait1 with trait2 ... {}
-
如果一个类在同时继承特质和父类时,应当把父类写在
extends
后。 -
特质中可以定义抽象和非抽象的属性和方法。
特质叠加引发两种冲突
第一种:一个类(
Sub
)混入的两个 trait(TraitA
,TraitB
)中具有相同的具体方法,且两个 trait 之间没有任何关系
如果当前父类和特质里面出现了相同的属性和方法,就会起冲突,必须在当前实现的子类(sub
)中进行重写。
举个栗子:
class Person {
val name: String = "Person"
var age: Int = 18
def sayHi(): Unit = {
println(s"hello from : $name")
}
}
trait Young {
// abstract and non-abstract attribute
var age: Int
val name: String = "young"
// method
def play(): Unit = {
println(s"young people $name is playing")
}
def dating(): Unit
}
trait Knowledge {
var amount: Int = 0
def increase(): Unit = {
amount += 1
}
}
trait Talent {
def increase(): Unit = {
println("increase talent")
}
}
class Student extends Person with Young with Knowledge with Talent{
override val name: String = "alice"
def dating(): Unit = {
println(s"Sutdent $name $age is dating")
}
def study(): Unit = println(s"Student $name is studying")
override def sayHi(): Unit = {
super.sayHi()
println(s"hello from : student $name")
}
override def increase(): Unit = {
super.increase()
println(s"studnet $name knowledge increase: $amount")
}
}
object Trait {
def main(args: Array[String]): Unit = {
val s = new Student()
s.sayHi()
s.increase()
s.study()
s.increase()
s.play()
s.increase()
# 总结
在这里,由于面试中MySQL问的比较多,因此也就在此以MySQL为例为大家总结分享。但是你要学习的往往不止这一点,还有一些主流框架的使用,Spring源码的学习,Mybatis源码的学习等等都是需要掌握的,我也把这些知识点都整理起来了
![面试真题](https://img-blog.csdnimg.cn/img_convert/c3f3c7e9741adfad8f1f9d4e3c539596.webp?x-oss-process=image/format,png)
![Spring源码笔记](https://img-blog.csdnimg.cn/img_convert/4bd783edf3b1e7ed7d878559b2c4cbe2.webp?x-oss-process=image/format,png)
dge increase: $amount")
}
}
object Trait {
def main(args: Array[String]): Unit = {
val s = new Student()
s.sayHi()
s.increase()
s.study()
s.increase()
s.play()
s.increase()
# 总结
在这里,由于面试中MySQL问的比较多,因此也就在此以MySQL为例为大家总结分享。但是你要学习的往往不止这一点,还有一些主流框架的使用,Spring源码的学习,Mybatis源码的学习等等都是需要掌握的,我也把这些知识点都整理起来了
[外链图片转存中...(img-Ow277Ef4-1714444902927)]
[外链图片转存中...(img-EdRrt8N1-1714444902928)]
> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.csdn.net/topics/618154847)收录**