唧唧复唧唧,木兰当户织。不闻机杼声,惟闻女叹息……
花木兰的故事大家都知道,今天就用这个故事来引出java的多态机制(ploymorphism)。
花木兰顶替着父亲花弧的名字,替父亲从军打仗,使用自己特有的本领,像佛山无形脚啊,罗汉拳啊,一箭三连啊去跟敌人打仗,这就是多态。
再比如你让一个人去吃饭,如果这个人是中国人的话,他会拿筷子吃饭;如果这个人是印度人,他会用手抓的方式去吃饭;如果这个人是美国人,它=他会用刀叉吃饭。同样是吃饭,不同的人有着不同的吃饭方法,这其实就是现实生活中的一种多态。多态就是实现了使用不同的方法来做不同的事情。
同样我们知道,JAVA是一种面向对象的语言,每一类的对象都会有着相同的方法,但每一个特别的对象就会产生不同的实现方法。
java中的多态指的是同一个方法调用,由于对象不同可能会有不同的行为。
说了这么多,没有代码可不行,这就来!!!
花木兰的实现代码
public class Test08 {
public static void main(String[] args) {
Zi huamulan=new Zi();
army(huamulan);
}
static void army(Fu a){
a.fight();
}
}
class Fu {
String kongfu1="降龙十八掌";
void fight(){
System.out.println("使用"+kongfu1+"上阵杀敌");
}
}
class Zi extends Fu{
String kongfu2="佛山无影脚";
String kongfu3="罗汉拳";
void fight(){
System.out.println("使用"+kongfu2+"上阵杀敌");
}
}
看了上面的代码,是不是感受到了多态的神奇呢
多态的要点
非常重要的知识点,敲黑板!!!
- 多态实现的三个必要条件:继承、方法重写、父类引用指向子类对象
- 多态是方法的多态,多态与属性无关
- 父类引用指向子类对象后,然后去调用子类重写的方法,这时多态就出现了
下面再看一个简单的多态测试,速上代码!
public class TestPolym {
public static void main(String[] args){
Animal a=new Animal(); //new一个Animal对象,调用animalCry()方法
animalCry(a);
Animal d=new Dog(); //采用向上自动转型,编译时会认为d是个动物对象,所以它调不出来Dog的特有方法
animalCry(d); //调用静态方法animalCry()时会调出来本质类型的方法,所以它会输出Dog的shout()方法
Dog d2=(Dog)d; //采用向下强制转换,又将狗强制转换成狗,现在编译器认为它就是一个狗的类型,所以可以调出狗的特有属性
d2.seedoor(); //运行时不会报错因为它本来就是狗
Animal c=new Cat(); //原理跟上同
animalCry(new Cat()); //这个是直接往里传了一个new的Cat对象,来调方法
//Dog d3=(Dog)c; //把猫强制转换成狗,进行强制类型转换时,编译时检查不出来但是运行时会报错,异常:java.lang.ClassCastException类型转换错误
//d3.seedoor(); //编译时它会认d3是狗,可以调用狗的方法,但运行时就检查出来了会报错
}
static void animalCry(Animal a){ //多态,父类引用指的是Animal a,指向子类对象指的是你传进来一个子类对象,就产生了方法的多态
a.shout();
}
}
class Animal{ //定义一个Animal父类
public void shout(){ //父类的shout()方法
System.out.println("叫了一声!");
}
}
class Dog extends Animal{ //定义一个Dog类继承Animal类
public void shout(){ //重写父类的方法
System.out.println("汪汪汪...");
}
public void seedoor(){ //子类的特有方法seedoor()
System.out.println("看门!");
}
}
class Cat extends Animal{ //跟Dog原理同
public void shout(){
System.out.println("喵喵喵...");
}
}
运行结果如下所示
当然,说了多态肯定离不开对象的转型,下面来说一下对象的转型问题
java中对象的转型分为向上自动类型转换和向下强制类型转换
向上自动类型转换
其实这跟以前的基本数据类型转换很相似,只不过把数据类型换成了对象类型
我们先以数据类型转换为例,基本数据类型的自动转换是由小类型转换为大类型
例如
double i=5; //5是int类型,自动转换为了double类型
同样对象的向上自动类型转换也是这样,即子类转换为父类
例如
Animal d=new Dog(); //采用向上自动转型,Dog类是子类,d就被转换成了父类Animal的对象
向下强制类型转换
同样,我们先以基本数据类型的强制转换为例,是由大类型向小类型转换
例如
int i=(int)5.2; //5.2为double类型,现在要将它强制转换为int,会损失其精度
对象的强制类型转换也就是父类转换为子类
例如
Animal d=new Dog(); //采用向上自动转型,编译时会认为d是个动物对象,所以它调不出来Dog的特有方法
Dog d2=(Dog)d; //这时,我们就需要再次将它转换为Dog类型,采用向下强制类型转换,只需要在要转换的对象前面加上括弧和要转换成的类名即可
当然,现在你可能会想,如果把一个猫对象给他强制转换为狗对象是不是也可以? 答案是否定的:不可以!!
强制类型转换易出现java.lang.ClassCastException的类型转换错误异常,这时我们为了避免异常的出现,可以使用instanceof运算符,先来给它进行个判断
instanceof是二元运算符,左边为对象,右边为类名,如果对象属于这个类则返回true,否则返回false
例如
Animal c=new Cat();
if (c instanceof Dog){
Dog d=(Dog)c;
}
else{
System.out.println("类型转换错误");
}
多态的好处
- 可扩充性:新增子类对象不影响类的多态,提高代码的可扩展性,符合开闭原则
- 接口性:其实多态相当于是父类通过自己的方法签名提供给子类的一个公共接口
- 简化性:有了多态极大的减少了对应用软件的代码编写与修改过程,提高了效率
说了这么多,终于要结束啦,第一次在CSDN上写东西,毕竟还在学习中,知识有限哈,如果哪里有错误欢迎指正哦,如果能看懂的话可以点个赞哈
哈哈下次见!