10类基础
本文最后更新于 2021-08-05 11:42:59
类基础
object ObjDemo1 {
def main(args: Array[String]): Unit = {
val user = new User
println(user.age)
println(user.name)
user.age=21
println(user.age)
user.age_$eq(11)
println(user.age)
user.eat()
println(user.getAge())
//给类起别名
type U = User
val u = new U
u.eat()
//打印的名字还是 User
println(u.getClass.getName())
}
}
/**
* 默认是public class
* 在java中 如果是public class 类名必须与文件名相同
* 内部类可以有private ,static
**/
class User{
//默认是私有的变量
//并且默认提供了 getter setter 但是不满足标准的javaBean规范,可以加上@BeanPropertity生成规范的,原来的也不会去掉
//比如 age -> age() ,age_$eq()
//但是age()不能用,age_$eq(xxx)可以用
// @beanGetter 只加get
// @beanSetter 只加set
@BeanProperty
var age =20
@BeanProperty
var name = "king"
//private final 且只有getter
val contry="china"
//private
//但是getter和setter是私有的了
private var sex = "man"
def eat()={
println(s"$name eat")
}
}
class User1{
//当属性为var时,可以使用 _ 占位不赋初值
//必须要手动指定类型
// 数字 默认0
// boolean 默认false
//引用类型 默认null
var name:String = _
var age:Int = _
}
class User3(var name:String,val age:Int,sex:String){
def eat={
println(sex)
}
}
//使用 有参主构造器 定义对象
//定义的参数自动成为成员变量
//如果没有指定 val或var 例如 sex ,则为private final ,如果内部没有使用,则会优化去掉(直接没有该成员变量)
class User4(@BeanProperty var name:String,val age:Int,sex:String){
//辅助构造器,相当于构造器重载
//辅助构造的参数就不是成员变量
def this(){
//第一行必须调用构造器
this("aaa",1,"")
}
def this(c:Int){
//后面的构造器可以调用前面定义辅助构造器的
//前面的构造器不能调用后面的辅助构造器
//this()
this("aa",c,"")
}
def eat={
println(sex)
}
}导包
object ObjDemo2 {
def main(args: Array[String]): Unit = {
//在任何地方导入包
//局部使用
import java.util.HashMap
val stringToString = new HashMap[String,String]()
//使用包对象
foo
}
}
//在priv.king.obj 下有一个类A
class A
package aa{
//在priv.king.obj.aa 下有一个类A
class A
}
/*
scala也有包的概念,命名于使用规则于java一样
1.包的声明
package priv.king.obj
2.包语句
在scala中, .scala文件一般会有多个类,所有的类都默认在一个包中
3.包使用
在文件最顶层导入
import java.util.HashMap
在代码任何需要的地方导入
比如在方法内导入
通配符导入
//导入util下所有包
import java.util._
//导入多个
import java.util.{HashMap,TreeMap}
//除了HashMap其他都导入
//导包的时候起别名
import java.util.{HashMap=>HM}
//除了HashMap其他都导入
//先给HashMap起别名,在导入所有
import java.util.{HashMap=>_ ,_}
//默认导入
//java中java.long.*
//scala中
java.lang._
scala._
scala.Predef._ Predef下所有的方法
*/包对象
package priv.king
/**
*
* @author king
* TIME: 2020/11/8 - 18:54
*
**/
//创建包对象
//包内的所有方法和属性,在包内的对象可以直接使用
//一个包下只能由一个包对象
package object obj {
def foo={
println("foo.......")
}
}
权限修饰符
object ObjDemo3 {
def main(args: Array[String]): Unit = {
// val hello = new Hello()
val hello2 = new Hello2(1)
}
}
//对主构造器私有
class Hello private(var age:Int){
//对成员变量私有
private var a=10
}
//对主构造器私有
//但是对obj包下所有的类公开 []
//指定公开对成员变量也适用
class Hello2 private[obj](var age:Int){
//对成员变量私有
private[obj] var a=10
}
/*
权限修饰符
java中
public:所有地方
protected: 同包和子类
[default]: 同包
private: 本类
scala中
[default] 默认是public
protected 子类
private 只能在本类
权限修饰灵活性
*/继承于多态
object ObjDemo4 {
def main(args: Array[String]): Unit = {
}
}
class QQQ(var arg:String){
private var a=1
protected var b=1
val c=222
def name()={
println("1111")
}
}
class WWW(var arg1:String) extends QQQ(arg1){
def fun={
// println(a) error
println(b)
}
//属性重写
//加上override关键字
override val c:Int=2
//子类重写必须加上override关键字
override def name(): Unit ={
super.name()
println("2222")
}
}
/*
单继承
构造器
先执行父构造器再执行子构造器
方法的重写必须加上override关键字
新概念:属性的重写
属性重写 加上override关键字
val只能重写val和不带参数的def
var只能重写抽象var
多态
java只有方法有多态,属性没有多态
scala中方法和属性都有多态
属性其实还是访问的是getter方法
*/抽象类
object ObjDemo5 {
def main(args: Array[String]): Unit = {
//匿名内部类
var aa = new ZZZ(10) {
override var b: Int = 1
override def foo(): Int = 1
}
}
}
abstract class ZZZ(var a:Int){
//抽象字段,不初始化
var b:Int
//抽象方法
//需要指定返回类型
def foo():Int
}
class XXX extends ZZZ(1){
override var b: Int = _
// ??? 实际上是调用Predef中的函数
//def ???:Nothing=throw new NotImplementedError
override def foo(): Int = ???
}
/*
scala抽象类
1.普通类有的抽象类都有
2.抽象类可以有抽象方法
3.抽象类不可以创建对象
*/object && 伴生类
object ObjDemo6 {
def main(args: Array[String]): Unit = {
CCC.fun
//apply 方法可以实现不用new 例如List()
//相当于调用CCC.apply()
//对象和类都有这个特性
println(CCC())
}
}
//CCC 相当于就是单例
//可以直接调用里面的方法
object CCC{
def fun=println("111")
//apply可以重载
def apply(): Int =10
}
//在一个.scala中有同名的object和class ,则称他们为伴生对象,伴生类
//编译过后 object中的相当于静态方法,class中的相当于非静态方法
//用来做静态工厂很方便
class CCC{
}object ObjDemo7 {
def main(args: Array[String]): Unit = {
println(Phone.getPhone("iphone"))
println(Phone.getPhone("huawei"))
println(Phone.getPhone("google"))
println(Phone.getPhone("google"))
}
}
object Phone{
val map=mutable.Map[String,Phone](
"iphone"->new Phone("iphone"),
"huawei"->new Phone("huawei")
)
def getPhone(brand:String)=map.getOrElseUpdate(brand,new Phone(brand))
}
class Phone private (var brand:String){
//相当于主构造器中的代码
println(s"$brand .........")
override def toString:String = s"品牌->$brand"
}
//iphone .........
//huawei .........
//品牌->iphone
//品牌->huawei
//google .........
//品牌->google
//品牌->googleTrait
object ObjDemo8 {
def main(args: Array[String]): Unit = {
val abc = new ABCtrait
abc.eat() //eat c
val dtrait = new Dtrait with Atrait
}
}
trait Atrait {
def eat(): Unit ={
println("eat a")
}
}
trait Btrait extends Atrait {
override def eat()={
super[Atrait].eat()
println("eat b")
}
}
trait Ctrait extends Atrait {
override def eat()={
super.eat()
println("eat c")
}
}
class Dtrait {
def fff()={
println("555555")
}
}
trait Etrait{
//自身类型
//相当于继承Dtrait
self:Dtrait=>
def fun()={
self.fff()
}
}
class ABCtrait extends Atrait with Btrait with Ctrait {
}
/*
没有父类:class 类名 extends 特质1 with 特质2 with 特质3 …
有父类:class 类名 extends 父类 with 特质1 with 特质2 with 特质3…
scala没有提供接口,但是提供了trait 编译后也是接口
1.抽象类中有的东西,trait都可以有
2.trait可以多混入
3.先混入的先初始化
4.如果一个类混入特质中有相同的方法,则会产生成员冲突,可以使用菱形结构解决问题(同时继承一个父类,在父类中定义方法),或者时在子类直接重写该方法
5.在多混入的菱形结构中,super调用前一个混入的方法,或者时 super[xxx]指定调用谁的
6.动态混入,,new B with A
7.trait也可以继承类,但是注意scala最终还是要去单继承
8.自身类型 self:XXX=> 相当于继承,将某个类注入到self变量中
*/类型转换
object ObjDemo9 {
def main(args: Array[String]): Unit = {
val kkk = new KKK
//类型判断
println(kkk.isInstanceOf[KKK])
println(kkk.isInstanceOf[LLL])
println(kkk.isInstanceOf[Object])
//类型转换
val lll = kkk.asInstanceOf[LLL]
}
}
class LLL
class KKK extends LLL枚举
object ObjDemo10 {
def main(args: Array[String]): Unit = {
var o = OOO1
println(OOO1.isInstanceOf[PPP])
println(Season.Spring)
println(Season.judge(1))
}
}
sealed abstract class PPP
object OOO1 extends PPP
object OOO2 extends PPP
object OOO3 extends PPP
object Season extends Enumeration{
type Season =Value //为了将Enumration.Value的类型暴露出来给外界使用
val Spring,Summer,Autumn,Winter =Value ///在这里定义具体的枚举实例
def judge(month:Int)={
if(month>=1 && month<=3) Spring
}
}
/*
sealed 修饰的类叫密封类
修饰后子类只能出现在当前文件中
1.模拟枚举
sealed abstract class PPP
object OOO1 extends PPP
2.java中编写,scala调用
3.继承Enumeration
*/10类基础
https://jiajun.xyz/2020/11/03/scala/10类基础/