继承:
class 子类名 extends 父类名 { 类体 }
(1)子类继承父类的属性和方法
(2)scala 是单继承
(3)继承的调用顺序:父类构造器->子类构造器
我们对比Java和Scala来看,注意两者的区别和相同之处.
Java:
public class TestExtends {
public static void main(String[] args) {
P1 p1 = new P1("tom",23);
StudentJ s1 = new StudentJ("jerry",22,"001",100);
}
}
class P1{
String name = null;
int age = 0;
public P1(){
System.out.println("我是父类的无参构造方法");
}
//构造方法
public P1(String name,int age){
System.out.println("我是带参数的构造方法");
this.age = age;
this.name = name;
}
}
class StudentJ extends P1{
String id = " ";
int grade = 0;
public StudentJ(String name,int age,String id,int grade){
System.out.println("我是子类的带参构造方法");
this.name = name;
this.age = age;
this.id = id;
this.grade = grade;
}
}
Scala:
object TestExtend {
def main(args: Array[String]): Unit = {
val t1 = new TeacherE("tom",24)
val t2 = new TeacherE("jerry",23,"清华大学","计算机科学与技术")
}
}
class PersonE{
var name :String = _
var age :Int = _
println("1、父类构造器调用")
def this(name:String,age:Int){
this()
this.age = age
this.name = name
println("2、父类的辅助构造器调用")
}
def PrintInfo(): Unit ={
println(s"person name = $name,age = $age")
}
}
class TeacherE(name:String,age:Int) extends PersonE(name,age){
var school: String = _
var subject:String = _
println("3、子类的主构造器")
def this(name:String,age:Int,school:String,subject:String){
this(name,age)
println("4、子类的辅助构造器")
this.school = school
this.subject = subject
}
override def PrintInfo(): Unit = {
println(s"person name = $name,age = $age,school = $school,subject = $subject")
}
}
运行结果为:
1、父类构造器调用
2、父类的辅助构造器调用
3、子类的主构造器
1、父类构造器调用
2、父类的辅助构造器调用
3、子类的主构造器
4、子类的辅助构造器
这是因为每次调用辅助构造器时都要先运行主构造器。最后重写了父类的PrintInfo方法。
多态:
多态指同一个实体同时具有多种形式。它是面向对象程序设计(OOP)的一个重要特征。
主要是指同一个对象,在不同时刻,代表的对象不一样,指的是对象的多种形态。
好处是可以把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,统一调用标准。
例如:水,在不同时刻可以有多种形态,包括水蒸气,冰,水。
Java怎么体现多态呢?狗有两种形态:狗和小动物
class Animal
class Dog extends Animal
Dog d = new Dog();//狗是狗
Animal a=new Dog();//狗是小动物,创建了狗的对象,赋值给动物对象,这就是多态
Java多态的特点:
1、 多态的前提是继承
2、 要有方法的重写
3、 父类引用指向子类对象,如:Animal a = new Dog(); -- 小到大,向上转型
4、 多态中,编译看左边,运行看右边
那么Scala的多态与Java有何不同呢?
先放结论:Scala中属性和方法都是动态绑定的,而Java中只有方法是动态绑定的。
public class bind {
public static void main(String[] args) {
People hurter1 = new Hurter();
System.out.println(hurter1.name);//alice=>父类的name
hurter1.printInfo();//hi,i am hurter,子类的方法
}
}
class People{
int age = 0;
String name = "alice";
public void printInfo(){
System.out.println("hi,i am people");
}
}
class Hurter extends People{
String name = "german";
@Override
public void printInfo(){
System.out.println("hi,i am hurter");
}
}
由上述例子可以看出,Java的属性不是动态绑定的。而方法调用是动态绑定的。
所以我们可以理解多态就是动态绑定!多态的对象只有在调用时才去判断它的类型从而决定调用的方法。
如果我要用多态获得子类的属性,显然Java是做不到的。
看一个Scala的例子:
package com.scala.learn
object Bind {
def main(args: Array[String]): Unit = {
val hunter:People = new Hunter//多态 左是父类型 右是子类型
println(hunter.name)
hunter.hello()
}
}
class People(){
val name:String = "jemmy"
def hello():Unit = {
println("i am people")
}
}
class Hunter() extends People(){
override val name: String = "bob"//继承自父类的方法和属性都要加override关键字
override def hello(): Unit = {
println("i am a hunter")
}
}
运行结果为:
bob
i am a hunter