abstract

Scala's abstract keywords are the same as java, abstract , and abstract classes cannot be instantiated.
In addition to the class can be defined as abstract, the properties and methods of the class can also be abstract.
From the following example, you can see that there is actually no difference between the abstract class definition of java

abstract class ScalaAbstract {
  // 抽象属性,可以没有初始值,甚至不用_
  var str1: String
  var str2: String = "str2"
  val str3: String
  val str4: String = "str4"

  /**
   * 抽象方法
   */
  def printInfo1: Unit

  def printInfo2: Unit = {
    println(s"${str1},${str2},${str3},${str4}")
  }
}

inherit

Like java, inheritance also uses the extends keyword, and the concept is the same as java, including calling the constructor of the parent class first. The differences are as follows:

  1. If you override the non-abstract methods and non-abstract variables of the parent class, you must write override in scala, which is just a warning in java.
  2. Abstract methods, abstract variables defined by var, can be written without override or can be written.
  3. The abstract variable defined by val must be written as override.
class ScalaChild extends ScalaAbstract {
  /**
   * 可以不写override
   */
  var str1: String = "str1"
  /**
   * 直接修改
   */
  str2 = "str2"
  /**
   * 必须写override
   */
  override val str3: String = "str3"
  /**
   * 必须写override
   */
  override val str4: String = "str4"

  /**
   * 抽象方法,可以不写override
   */
  def printInfo1: Unit = {
    println(s"${str1},${str2},${str3},${str4}")
  }

  /**
   * 必须写override
   */
  override def printInfo2: Unit = {
    println(s"ScalaChild:${str1},${str2},${str3},${str4}")
  }
}

object ScalaChild {
  def main(args: Array[String]): Unit = {
    val child = new ScalaChild()
    child.printInfo1
    child.printInfo2
  }
}

Polymorphism

Let's take a look at the more familiar java.
An abstract class JavaAnimal is defined, which contains a variable name and method eat. JavaCat and JavaDog are implementation classes of JavaAnimal. In the main method, use the eat method to print.

public abstract class JavaAnimal {
    public String name = "无";

    abstract void eat();
}

public class JavaCat extends JavaAnimal {
    String name = "小猫";

    void eat() {
        System.out.println("吃鱼");
    }
}

public class JavaDog extends JavaAnimal {
    String name = "小狗";

    void eat() {
        System.out.println("吃骨头");
    }
}

public class JavaAnimalMain {
    public static void eat(JavaAnimal animal) {
        System.out.println(animal.name);
        animal.eat();
    }

    public static void main(String[] args) {
        eat(new JavaCat());
        eat(new JavaDog());
    }
}

The print result is:

无
吃鱼
无
吃骨头

You can see that name is the value of the parent class, but the method is to call the method of the subclass.
In scala, similar functions are achieved:

abstract class ScalaAnimal {
  var name: String = "无"

  def eat(): Unit
}

object ScalaAnimal {
  def eat(animal: ScalaAnimal): Unit = {
    println("******")
    println(animal.name)
    animal.eat()
  }

  def main(args: Array[String]): Unit = {
    eat(new ScalaCat)
    eat(new ScalaDog)
  }
}

class ScalaCat extends ScalaAnimal {
  name = "小猫"

  override def eat(): Unit = {
    println("吃鱼")
  }
}

class ScalaDog extends ScalaAnimal {
  name = "小狗"

  override def eat(): Unit = {
    println("吃骨头")
  }
}

Print result:

******
小猫
吃鱼
******
小狗
吃骨头

The name prints the name of the subclass.
Therefore, properties in java are statically bound, and methods are dynamically bound. In scala, properties and methods are bound dynamically.


大军
847 声望183 粉丝

学而不思则罔,思而不学则殆


引用和评论

1 篇内容引用
0 条评论