Scala学习笔记(八)----类型问题
2016-06-29 14:28
459 查看
先看一段 java代码public class test
{
public static void main(String[] args) throws ClassNotFoundException, SQLException
{
List<Pet> list = new ArrayList<Pet>();
list.add(new Dog("Limbo",1));
list.add(new Dog("Yu",1));
workWithPets(list);
}
public static void workWithPets(List<Pet> list)
{
for(Pet p : list)
{
System.out.println(p);
}
}
}
class Pet{
private String name;
private int age;
public Pet(){}
public Pet(String name,int age)
{
this.name = name;
this.age = age;
// TODO Auto-generated constructor stub
}
@Override
public String toString()
{
return "name: "+ this.name +" age: "+ this.age;
}
}
class Dog extends Pet{
public Dog(String name,int age)
{
super(name,age);
// TODO Auto-generated constructor stub
}
}OK,这一段代码编译执行均无问题
接下来让我们看一段Scala代码
class Pets(var name:String,var age:Int) {
override def toString() :String = {"name: " + name + " age: " + age}
}
class Dog(override var name:String,override var age:Int )extends Pets(name, age)
{}
object test3{
def main(args: Array[String]): Unit = {
val dogs = Array(new Dog("Limbo",1),new Dog("Yu",2))
workWithPets(dogs) //Compiling Error
}
def workWithPets(pets:Array[Pets])={
pets.foreach(println)
}
}
调用workWithPets()的时候,Scala会提示错误,Dog数组不能穿给接收Pet数组的方法,但是,对这个方法而言,这么做没有什么不良后果。不过Scala不知道这一点,它试图保护我们。我们需要做的就是告诉Scala这样做是可行的
def workWithPets[T <: Pet](pets:Array[T])={
pets.foreach(println)
}这里用特殊的语法定义了workWithPets()。 T <: Pet 表示T所代表的类派生自Pet。通过使用这种上界语法,我们告诉Scala,具有参数化类型T的类型T的参数数组必须至少是Pet的数组,也可以是Pet的派生类的数组。
协变:将子类实例的容器赋给基类容器的能力
逆变:将超类实例的容器赋给子类容器的能力
例子:
{
public static void main(String[] args) throws ClassNotFoundException, SQLException
{
List<Pet> list = new ArrayList<Pet>();
list.add(new Dog("Limbo",1));
list.add(new Dog("Yu",1));
workWithPets(list);
}
public static void workWithPets(List<Pet> list)
{
for(Pet p : list)
{
System.out.println(p);
}
}
}
class Pet{
private String name;
private int age;
public Pet(){}
public Pet(String name,int age)
{
this.name = name;
this.age = age;
// TODO Auto-generated constructor stub
}
@Override
public String toString()
{
return "name: "+ this.name +" age: "+ this.age;
}
}
class Dog extends Pet{
public Dog(String name,int age)
{
super(name,age);
// TODO Auto-generated constructor stub
}
}OK,这一段代码编译执行均无问题
接下来让我们看一段Scala代码
class Pets(var name:String,var age:Int) {
override def toString() :String = {"name: " + name + " age: " + age}
}
class Dog(override var name:String,override var age:Int )extends Pets(name, age)
{}
object test3{
def main(args: Array[String]): Unit = {
val dogs = Array(new Dog("Limbo",1),new Dog("Yu",2))
workWithPets(dogs) //Compiling Error
}
def workWithPets(pets:Array[Pets])={
pets.foreach(println)
}
}
调用workWithPets()的时候,Scala会提示错误,Dog数组不能穿给接收Pet数组的方法,但是,对这个方法而言,这么做没有什么不良后果。不过Scala不知道这一点,它试图保护我们。我们需要做的就是告诉Scala这样做是可行的
def workWithPets[T <: Pet](pets:Array[T])={
pets.foreach(println)
}这里用特殊的语法定义了workWithPets()。 T <: Pet 表示T所代表的类派生自Pet。通过使用这种上界语法,我们告诉Scala,具有参数化类型T的类型T的参数数组必须至少是Pet的数组,也可以是Pet的派生类的数组。
协变:将子类实例的容器赋给基类容器的能力
逆变:将超类实例的容器赋给子类容器的能力
例子:
如果一个方法要接受Dog参数,那么另一个接受Animal参数的方法肯定也可以接受这个方法的参数,这是Animal向Dog方向的转变是逆变。如果一个方法要求的返回值是Animal,那么返回Dog的方法肯定是可以满足其返回值要求的,这是Dog向Animal方向的转变是协变。
相关文章推荐
- [DUBBO] Decode rpc invocation failed: null, dubbo version: 2.8.4, current host: 127.0.0.1
- 侧滑(以Activity为页面)
- Spring3.1包详解与依赖关系
- Java实现MD5加密与解密
- mysql-批量修改表字段中的某一部分内容
- [Android]Android端ORM框架——RapidORM(v2.0)
- 用C#获取局域网内所有机器
- lua学习笔记二--函数
- ERP自定义查询,可直接查MES站点数据
- Eclipse 3.7手工安装Maven2的插件(包含POM图形编辑工具)
- Spark(1)
- CYQ.Data V5 MDataTable 专属篇介绍
- 啊里大鱼短信发送API
- 工作经验总结201606
- php 一次性替换多个关键词
- python头部注释 vim添加头部注释
- 错误: 类A是公共的, 应在名为A.java 的文件中声明
- 融云头像问题
- .NET MVC标签扩展(checkbox,radio)
- 数据结构复习——线性表的顺序存储实现