一、Scala程序的运行方式
1.main方法:只可以在单例对象或伴生对象中定义
1 object test1 { 2 3 def main(args: Array[String]): Unit = { 4 println("我是main主入口") 5 } 6 //我是main主入口 7 8 }
2.App Trait(特质):继承自App类
1 object test1 extends App { 2 println("我是特质运行方式") 3 //我是特质运行方式 4 5 }
二、继承 extends
1.在Scala中继承是单根体系,所有类型都只有一个父类
1 class Person {} 2 3 class User { 4 var name = "cmx" 5 } 6 7 def main(args: Array[String]): Unit = { 8 var a = new User() 9 println(a.name) 10 }
2.继承后m,父类中的成员属性和方法,子类都可以继承下来
1 class Person { 2 var name = "cmx" 3 4 def func = println("我是一个方法") 5 } 6 7 class User extends Person { 8 9 } 10 11 def main(args: Array[String]): Unit = { 12 var user = new User 13 println(user.name) 14 user.func 15 //cmx 16 //我是一个方法 17 }
3.private,protected 访问修饰词依据有效
private:只可以在本类中使用,子类中用不了
protected:只可以在本类中或子类中使用,外部用不了
4.重写/覆盖:子类可以重写父类的属性和方法(当然子类可以自己定义新的属性与方法,这里不做演示)
1 class Person { 2 //注意重写的属性 定义时关键字要用val 3 val name = "cmx" 4 5 def func = println("我是一个方法") 6 } 7 8 class User extends Person { 9 override val name = "cmx01" 10 11 override def func = println("我是子类的func方法") 12 } 13 14 def main(args: Array[String]): Unit = { 15 var user = new User 16 println(user.name) 17 user.func 18 //cmx01 19 //我是子类的func方法 20 }
5.类和单例对象均可以继承一个类
1 class Person { 2 var name = "cmx" 3 4 def func = println("我是一个方法") 5 } 6 7 object User extends Person { 8 9 } 10 11 def main(args: Array[String]): Unit = { 12 println(User.name) 13 User.func 14 //cmx 15 //我是一个方法 16 }
6.super 关键字:子类可以通过super 访问父类公开的和 protected 修饰的成员方法,但是在Scala中不可以访问成员属性
作用:表达概念更清晰
如果在覆盖情况下,通过super关键字 明确使用父类的方法
1 class Cmx { 2 var name = "cmx" 3 protected var age = 11 4 5 def func = { 6 println("我是父类的方法") 7 } 8 } 9 10 class Cmx01 extends Cmx { 11 override def func = { 12 println("我是子类覆盖父类的方法") 13 } 14 15 def get_func = { 16 func 17 super.func 18 } 19 } 20 21 def main(args: Array[String]): Unit = { 22 var a = new Cmx01 23 a.get_func 24 //我是子类覆盖父类的方法 25 //我是父类的方法 26 }
三、多态性
特点:1.用父类型的变量接收子类行的对象
2.多态在调用过程中,只可以调用父类定义的方法
3.在运行时,若子类重写(覆盖)了父类的方法,会执行子类的方法
注意:定义多态的对象时不能使用类型推导
1 class Cmx { 2 def func = { 3 println("我是父类的方法1") 4 } 5 6 def func1 = { 7 println("我是父类的方法2") 8 } 9 } 10 11 class Cmx01 extends Cmx { 12 override def func = { 13 println("我是子类覆盖父类的方法1") 14 } 15 16 def func2 = { 17 println("我是子类自定义的方法1") 18 } 19 20 } 21 22 def main(args: Array[String]): Unit = { 23 var a: Cmx = new Cmx01 24 //多态变量 使用父类方法,却被子类覆盖,最后调用子类 25 a.func 26 //结果 27 //我是子类覆盖父类的方法1 28 29 //多态变量,调用父类的方法 30 a.func1 31 //结果 32 //我是父类的方法2 33 34 //当多态变量欲调用子类自定义的方法时 ,报错 35 a.func2 36 //Error:(45, 7) value func2 is not a member of cmx_test.test1.Cmx 37 // a.func2 38 }
多态性的好处:解耦合;增加通用性
1 class Animal { 2 def eat: Unit = { 3 println("动物吃东西") 4 } 5 } 6 7 class Dog extends Animal { 8 override def eat: Unit = { 9 println("狗吃骨头") 10 } 11 } 12 13 class Cat extends Animal { 14 override def eat: Unit = { 15 println("猫吃猫粮") 16 } 17 } 18 19 def get_eat(animal: Animal): Unit = { 20 animal.eat 21 } 22 23 def main(args: Array[String]): Unit = { 24 //解耦合 25 // var a: Animal = new Dog 26 // a.eat 27 //狗吃骨头 28 29 //增加通用性 30 get_eat(new Dog) 31 get_eat(new Cat) 32 //狗吃骨头 33 //猫吃猫粮 34 }
类型转换:在多态类型中,把父类型转换成子类型
1 class Animal { 2 def eat: Unit = { 3 println("动物吃东西") 4 } 5 } 6 7 class Dog extends Animal { 8 override def eat: Unit = { 9 println("狗吃骨头") 10 } 11 12 def jiao: Unit = { 13 println("会叫") 14 } 15 } 16 17 def main(args: Array[String]): Unit = { 18 var a: Animal = new Dog 19 if (a.isInstanceOf[Dog]) { 20 var b = a.asInstanceOf[Dog] 21 b.jiao 22 }23 }
isInstanceOf 不能准确的判断出 一个类型 是具体的子类 还是 父类
1 class Animal { 2 def eat: Unit = { 3 println("动物吃东西") 4 } 5 } 6 7 class Dog extends Animal { 8 override def eat: Unit = { 9 println("狗吃骨头") 10 } 11 12 def jiao: Unit = { 13 println("会叫") 14 } 15 } 16 17 def main(args: Array[String]): Unit = { 18 var a: Animal = new Dog 19 println(a.isInstanceOf[Dog]) 20 println(a.isInstanceOf[Animal]) 21 //true 22 //true 23 24 //使用以下方法比较严谨 25 println(a.getClass==classOf[Dog]) 26 //true 27 //判断a的实际类型 28 println(a.getClass) 29 //class cmx_test.test1$Dog 30 //判断类型的实际类型 31 println(classOf[Animal]) 32 //class cmx_test.test1$Dog
四、抽象类
定义:在定义类时,引入abstract 关键字的类叫做抽象类
特点:1.不可实例化对象
2.抽象类中可以定义普通方法和属性,也可以定义抽象方法和属性
3.有抽象方法,属性的类时抽象类,但抽象类可以没有抽象方法和抽象属性
4.抽象类通过子类继承实现自己的价值,但是其中的抽象方法和抽象属性必须全部重写,不然该类依然是个抽象类,不可以实例化
开发的价值:若一个类,仅仅是一个抽象的概念,那么我们就可以把它定义为抽象类,并通过子类来进行使用
1 abstract class Shape { 2 //抽象属性定义 3 //val name: String 4 var name: String 5 6 //抽象方法定义 7 def area: Double 8 } 9 10 class Cycle(var rate: Double) extends Shape { 11 //重写的抽象属性(这里和普通的重写不同,使用var/val关键字均可) 12 //override val name = "cmx" 13 override var name = "cmx" 14 15 //重写的抽象方法 16 override def area: Double = { 17 rate * rate * Math.PI 18 } 19 } 20 21 class Rect(var length: Double, var Double) extends Shape { 22 //override val name = "cmx01" 23 override var name = "cmx01" 24 25 override def area: Double = { 26 length * width 27 } 28 } 29 30 //利用多态性:用父类行接受子类的对象 31 def test(s: Shape): Double = { 32 s.area 33 34 } 35 36 def main(args: Array[String]): Unit = { 37 println(test(new Cycle(10.0))) 38 println(test(new Rect(10.0, 14.0))) 39 //314.1592653589793 40 //140.0 41 }