斯卡拉 |自类型注解
特征的自我类型注释是this的假定类型,在特征中,要使用的接收者。任何混入特征的具体类都必须确保其自身类型符合混入的特征。这意味着使用自我类型不会将局部变量和方法暴露给其子类和子特征。将一个大类划分为几个特征是自我类型最常见的用法。自类型是一种声明必须将特征混合到另一个特征或类中的方法,即使它不直接扩展它,这使得那些混合特征的依赖项的成员无需导入即可使用。
要在 trait 中使用 self 类型,请写入identifier_name ,在其旁边是要混合的 trait类型,然后是 => 符号;如下所示。
句法:
trait A{
//statements
}
trait B{
this: A => //here we can use methods & variables of trait A
}
让我们讨论一些例子。
例子 :
// Scala Program that uses self type
trait with_powers
{
var mind ="extra-ordinary";
}
trait without_powers
{
var mind="ordinary";
}
trait person
{
def brain();
}
// class extend trait
class extraordinary_person extends person
{
// reassign this
this: with_powers =>
override def brain() = println(s"super hero brain is $mind!");
}
// class extend trait
class ordinary_person extends person
{
// reassign this
this: without_powers =>
override def brain() = println(s"normal human brain is $mind.");
}
// Creating object
object GFG
{
// Main method
def main(args:Array[String])
{
val hero = new extraordinary_person() with with_powers;
val mohan = new ordinary_person() with without_powers;
//val mohan= new ordinary_person() with with_powers; ERROR
//does not conform to ordinary_person's self type
hero.brain();
mohan.brain();
}
}
输出 :
super hero brain is extra-ordinary!.
normal human brain is ordinary.
在上面的示例中,我们创建了带有_powers、没有_powers 和person 的特征。这里的类非凡人扩展了特质人。类似的 class normal_person 也扩展了 trait person。通过使用此特征名称 => 在两个类中都发生自我类型注释
val mohan= new normal_person() with_powers;显示错误不符合普通人的自我类型。
例子 :
// Scala Program that uses self type
trait A
{
def x = 1;
}
// trait extend another trait
trait B extends A
{
override def x = super.x * 5;
}
// trait extend another trait
trait C1 extends B
{
override def x = 2;
}
// trait extend another trait
trait C2 extends A
{
this: B=> override def x = 2;
}
// Creating object
object GFG
{
// Main method
def main(args:Array[String])
{
println((new C1 with B).x);
println((new C2 with B).x);
}
}
输出 :
2
10
在这里,在上面的示例中,C2 是 C2 与 B 的抽象类型和自身类型。 ((new C2 with B)) 符合 C2 与 B 的自身类型 (this: B=>) 因此,自我类型允许您指定什么类型的特征被允许混合。
例子 :
// Scala Program that uses self type
trait Being
{
var name: String
var age: Int
var gender: String
}
// Creating trait
trait Sayings
{
this: Being =>
def greetings(greet: String) = println(s"$name: $greet");
def info() = println(s"I am $age years old $gender");
}
// extend both trait with single class
class Person(var r_name: String, var r_age: Int,
var r_gender: String)
extends Sayings with Being
{
var name = s"Person $r_name";
var age = r_age;
var gender = r_gender;
}
// Creating object
object GFG
{
// Main method
def main(args: Array[String])
{
val person = new Person("Lakshya", 24, "Male");
person.greetings("hello, hi there!!");
person.info();
}
}
输出 :
Person Lakshya: hello, hi there!!
I am 24 years old Male
在上面的例子中(这个:Being =>)它基本上意味着变量的名字、年龄、性别现在在问候和信息方法的范围内,但没有将它们暴露给任何其他扩展它的子类或特征。因此,self 类型指定了应混入特征类型的任何具体类的要求。