Java基础12 类型转换与多态
2014-01-22 08:58
761 查看
作者:Vamei出处:http://www.cnblogs.com/vamei欢迎转载,也请保留这段声明。谢谢!
我们之前使用类创造新的类型(type),并使用继承来便利我们创建类的过程。我将在这一讲中深入类型,并介绍多态(polymorphism)的概念。
Java的任意变量和引用经过类型声明(typedeclaration),才能使用。我们之前见过对象数据、类数据、方法参数、方法返回值以及方法内部的自动变量,它们都需要声明其类型。Java是一种强类型(strongly
typing)语言,它会对类型进行检查。如果我们错误的使用类型,将造成错误。
类型不符,卖萌无效
比如在下面的Test类中,我们将一个Cup类对象赋予给aPerson类引用:
javac将返回:
found:Cup
required:Human
aPerson=newCup();
^
1error
Java可以对基本类型的变量进行类型转换。不同的基本类型有不同的长度和存储范围。如果我们从一个高精度类型转换到低精度类型,比如从float转换到int,那么我们有可能会损失信息。这样的转换叫做收缩变换(narrowingconversion)。这种情况下,我们需要显示的声明类型转换,比如:
如果我们从低精度类型转换成高精度类型,则不存在信息损失的顾虑。这样的变换叫做宽松变换(wideningconversion)。我们不需要显示的要求类型转换,Java可以自动进行:
基本类型转换
在Java中,引用也可以进行类型转换,但是有限制。
我们可以将一个衍生类引用转换为其基类引用,这叫做向上转换(upcast)或者宽松转换。下面的BrokenCup类继承自Cup类,并覆盖了Cup类中原有的addWater()和drinkWater()方法:
程序运行结果:
shit,brokencup
在上面可以看到,不需要任何显示说明,我们将衍生类引用aBrokenCup赋予给它的基类引用aCup。类型转换将由Java自动进行。
我们随后调用了aCup(我们声明它为Cup类型)的addWater()方法。尽管aCup是Cup类型的引用,它实际上调用的是BrokenCup的addWater()方法!也就是说,即使我们经过upcast,将引用的类型宽松为其基类,Java依然能正确的识别对象本身的类型,并调用正确的方法。Java可以根据当前状况,识别对象的真实类型,这叫做多态(polymorphism)。多态是面向对象的一个重要方面。
多态是Java的支持的一种机制,同时也是面向对象的一个重要概念。这提出了一个分类学的问题,既子类对象实际上“是”父类对象。比如一只鸟,也是一个动物;一辆汽车,也必然是一个交通工具。Java告诉我们,一个衍生类对象可以当做一个基类对象使用,而Java会正确的处理这种情况。
比如下面的继承关系:
我们可以说用杯子(Cup)喝水(drinkWater)。实际上,喝水这个动作具体含义会在衍生类中发生很大变换。比如用吸管喝水,和从一个破杯子喝水,这两个动作差别会很大,虽然我们抽象中都讲“喝水”。我们当然可以针对每个衍生类分别编程,调用不同的drinkWater方法。然而,作为程序员,我们可以对杯子编程,调用Cup的drinkWater()方法,而无论这个杯子是什么样的衍生类杯子。Java会调用相应的正确方法,正如我们在上面程序中看到的。
看一个更加有意义的例子,我们给Human类增加一个drink()方法,这个方法接收一个杯子对象和一个整数作为参数。整数表示喝水的水量:
程序运行结果:
shit,nowaterinside
我们在Human类的drink()的定义中,要求第一个参量为Cup类型的引用。但在实际运用时(Test类),将Cup的BrokenCup衍生类对象。这实际上是将hisCup向上转型称为Cup类,传递给drink()方法。在方法中,我们调用了drinkWater()方法。Java发现这个对象实际上是BrokenCup对象,所以实际调用了BrokenCup的相应方法。
我们可以将一个基类引用向下转型(downcast)成为衍生类的引用,但要求该基类引用所指向的对象,已经是所要downcast的衍生类对象。比如可以将上面的hisCup向上转型为Cup类引用后,再向下转型成为BrokenCup类引用。
Java中,所有的类实际上都有一个共同的继承祖先,即Object类。Object类提供了一些方法,比如toString()。我们可以在自己的类定义中覆盖这些方法。
Object:祖先
我们可以编写一个操作Object对象的程序,就可以通过upcast,将任意对象传递给该程序。
我将在以后深入Object类。
(多态的实现是依靠RTTI的支持。我将在以后深入。)
基本类型转换
polymorphism
downcast
Object
我们之前使用类创造新的类型(type),并使用继承来便利我们创建类的过程。我将在这一讲中深入类型,并介绍多态(polymorphism)的概念。
类型检查
Java的任意变量和引用经过类型声明(typedeclaration),才能使用。我们之前见过对象数据、类数据、方法参数、方法返回值以及方法内部的自动变量,它们都需要声明其类型。Java是一种强类型(stronglytyping)语言,它会对类型进行检查。如果我们错误的使用类型,将造成错误。
类型不符,卖萌无效
比如在下面的Test类中,我们将一个Cup类对象赋予给aPerson类引用:
publicclassTest { publicstaticvoidmain(String[]args) { HumanaPerson; aPerson=newCup(); } } classHuman { /** *constructor */ publicHuman(inth) { this.height=h; } /** *accessor */ publicintgetHeight() { returnthis.height; } /** *mutator */ publicvoidgrowHeight(inth) { this.height=this.height+h; } privateintheight; } classCup { publicvoidaddWater(intw) { this.water=this.water+w; } publicvoiddrinkWater(intw) { this.water=this.water-w; } privateintwater=0; }
javac将返回:
found:Cup
required:Human
aPerson=newCup();
^
1error
基本类型转换
Java可以对基本类型的变量进行类型转换。不同的基本类型有不同的长度和存储范围。如果我们从一个高精度类型转换到低精度类型,比如从float转换到int,那么我们有可能会损失信息。这样的转换叫做收缩变换(narrowingconversion)。这种情况下,我们需要显示的声明类型转换,比如:publicclassTest { publicstaticvoidmain(String[]args) { inta; a=(int)1.23;//narrowingconversion System.out.println(a); } }
如果我们从低精度类型转换成高精度类型,则不存在信息损失的顾虑。这样的变换叫做宽松变换(wideningconversion)。我们不需要显示的要求类型转换,Java可以自动进行:
publicclassTest { publicstaticvoidmain(String[]args) { inta=3; doubleb; b=a;//wideningconversion System.out.println(a); } }
基本类型转换
upcast与多态
在Java中,引用也可以进行类型转换,但是有限制。我们可以将一个衍生类引用转换为其基类引用,这叫做向上转换(upcast)或者宽松转换。下面的BrokenCup类继承自Cup类,并覆盖了Cup类中原有的addWater()和drinkWater()方法:
publicclassTest
{
publicstaticvoidmain(String[]args)
{
CupaCup;
BrokenCupaBrokenCup=newBrokenCup();
aCup=aBrokenCup;//upcast
aCup.addWater(10);//methodbinding
}
}
classCup
{
publicvoidaddWater(intw)
{
this.water=this.water+w;
}
publicvoiddrinkWater(intw)
{
this.water=this.water-w;
}
privateintwater=0;
}
classBrokenCupextendsCup
{
publicvoidaddWater(intw)
{
System.out.println("shit,brokencup");
}
publicvoiddrinkWater(intw)
{
System.out.println("om...num...,nowaterinside");
}
}
程序运行结果:
shit,brokencup
在上面可以看到,不需要任何显示说明,我们将衍生类引用aBrokenCup赋予给它的基类引用aCup。类型转换将由Java自动进行。
我们随后调用了aCup(我们声明它为Cup类型)的addWater()方法。尽管aCup是Cup类型的引用,它实际上调用的是BrokenCup的addWater()方法!也就是说,即使我们经过upcast,将引用的类型宽松为其基类,Java依然能正确的识别对象本身的类型,并调用正确的方法。Java可以根据当前状况,识别对象的真实类型,这叫做多态(polymorphism)。多态是面向对象的一个重要方面。
多态是Java的支持的一种机制,同时也是面向对象的一个重要概念。这提出了一个分类学的问题,既子类对象实际上“是”父类对象。比如一只鸟,也是一个动物;一辆汽车,也必然是一个交通工具。Java告诉我们,一个衍生类对象可以当做一个基类对象使用,而Java会正确的处理这种情况。
比如下面的继承关系:
我们可以说用杯子(Cup)喝水(drinkWater)。实际上,喝水这个动作具体含义会在衍生类中发生很大变换。比如用吸管喝水,和从一个破杯子喝水,这两个动作差别会很大,虽然我们抽象中都讲“喝水”。我们当然可以针对每个衍生类分别编程,调用不同的drinkWater方法。然而,作为程序员,我们可以对杯子编程,调用Cup的drinkWater()方法,而无论这个杯子是什么样的衍生类杯子。Java会调用相应的正确方法,正如我们在上面程序中看到的。
看一个更加有意义的例子,我们给Human类增加一个drink()方法,这个方法接收一个杯子对象和一个整数作为参数。整数表示喝水的水量:
publicclassTest
{
publicstaticvoidmain(String[]args)
{
Humanguest=newHuman();
BrokenCuphisCup=newBrokenCup();
guest.drink(hisCup,10);
}
}
classHuman
{
voiddrink(CupaCup,intw)
{
aCup.drinkWater(w);
}
}
程序运行结果:
shit,nowaterinside
我们在Human类的drink()的定义中,要求第一个参量为Cup类型的引用。但在实际运用时(Test类),将Cup的BrokenCup衍生类对象。这实际上是将hisCup向上转型称为Cup类,传递给drink()方法。在方法中,我们调用了drinkWater()方法。Java发现这个对象实际上是BrokenCup对象,所以实际调用了BrokenCup的相应方法。
downcast
我们可以将一个基类引用向下转型(downcast)成为衍生类的引用,但要求该基类引用所指向的对象,已经是所要downcast的衍生类对象。比如可以将上面的hisCup向上转型为Cup类引用后,再向下转型成为BrokenCup类引用。
Object类型
Java中,所有的类实际上都有一个共同的继承祖先,即Object类。Object类提供了一些方法,比如toString()。我们可以在自己的类定义中覆盖这些方法。Object:祖先
我们可以编写一个操作Object对象的程序,就可以通过upcast,将任意对象传递给该程序。
我将在以后深入Object类。
总结
基本类型转换polymorphism
downcast
Object
相关文章推荐
- Java基础12 类型转换与多态
- Java基础12 类型转换与多态
- Java基础12 类型转换与多态
- Java基础12 类型转换与多态
- Java基础12 类型转换与多态
- Java基础12 类型转换与多态
- Java基础12 类型转换与多态
- Java基础教程之类型转换与多态
- Java基础学习之final和多态及类型转换
- java Vamei快速教程12 类型转换和多态
- Java基础——类型转换与多态
- Java基础----类型转换与多态
- Java基础——类型转换与多态
- java语言基础——5类型转换
- Android中的java基础(二)——装箱与拆箱及不同基本类型的比较(类型转换)
- 黑马程序员_Java基础(环境搭建,常量变量,类型转换,运算符,控制语句)
- Java基础--基本数据类型转换
- java基础中的数据类型的转换问题
- Java基础-基本数据类型转换案例
- java学习:对象的类型转换、多态