关键步骤如下。
向上转型完成多态。
向下转型完成调用子类方法。
上转型前使用istancof判断。
Java面向对象还有一个重要的特性:多态。
1.认识多态多态一词的通常含义是指能够呈现出多种不同的形式或形态。而在程序设计的术语中,它意味着一个特定类型的变量可以引用不同类型的对象,并且能自动地调用引用的对象的方法,也就是根据作用到的不同对象类型,响应不同的操作。方法重写是实现多态的基础。通过下面这个例子可以简单认识什么是多态。
示例7
有一个宠物类Pet,它有几个子类,如Bird(小鸟)、Dog(狗)等,其中宠物类定义了看病的方法toHospital(),子类分别重写了 看病的方法。请在main()方法中分别实例化各种具体的宠物,并调用看病的方法。
关键代码:
//Pet父类 class Pet {public void toHospital() {System.out.pintln("宠物看病!");} } //Dog子类继承Pet父类 class Dog extends Pet{public void toHospital () {System.out.println("狗狗看病");} } //Bird子类继承Pet父类 class Bird extends Pet{public void toHospital (){System.out.println("小鸟看病");}} //以上为Pet和其子类代码,以下为调用代码 public class Test {public static void main(String args[]) {Dog dog = new Dog();dog.toHospital;//狗狗看病Bird bird = new Bird();bird.toptal();//小鸟看病} }
12345678910111213141516171819202122232425262728293031输出结果:
狗狗看病 小鸟看病 12
也可以用示例8的代码实现相同功能。
示例8
请将示例7的实现方式进行修改。
关键代码:
public class Test {public static void main(String[] args) {Pet pet;pet=new Dog();pet.toHospital();//狗狗看病pet=new Bird();pet.toHospital();//小鸟看病} } 123456789
示例8和示例7中两段Test类的代码运行效果完全一样。 虽然示例8中测试类里定义的是Pet类, 但实际执行时都是调用Pet子类的方法。示例8中的代码就体现了多态性。
多态意味着在一次方法调用中根据包含的对象的实际类型(即实际的子类对象)来决定应调用哪个方法,而不是由用来存储对象引用的变量的类型决定的。当调用一个方法时,为了实现多态的操作,这个方法既是在父类中 声明过的,也必须是在子类中重写过的方法。
示例8中的!Pet类声明为抽象类,因为其本身实例化没有任何意义,toHospital()方法声明为抽象方法。本章后面的代码中Pet都将以抽象类存在, Pet中的toHospita()方法都将以抽象方法存在,关于抽象类和抽象方法会在后续章节中讲解。
提示
(1)抽象类不能被实例化。
(2)子类如果不是抽象类,则必须重写抽象类中的全部抽象方法。
(3)abstract修饰符不能和final修饰符一 起使用。
(4)abstract修饰的抽象方法没有方法体。
(5)private 关键字不能用来修饰抽象方法。
子类向父类的转换称为向上转型。
向上转型的语法格式如下。
<父类型><引用变量名>=new<子类型>(); 1
之前介绍了基本数据类型之间的类型转换,举例如下。
(1)把int型常量或变量的值赋给double型变量,可以自动进行类型转换。
int i=5; double d1 = 5; 12
(2)把double型常量或变量的值赋给int 型变量,必须进行强制类型转换。
double d2= 3.14; int a = (int)d2; 12
实际上在引用数据类型的子类和父类之间也存在着类型转换问题,如示例8中的代码。
//Pet为抽象父类,Dog 为子类,Pet 中包含抽象方法toHospital() Pet pet=new Dog();//子类到父类的转换 //会调用Dog类的toHospital()方法,而不是 Pet类的toHospital(方法,体现了 多态pet.toHospital(); 123
提示
Pet对象无法调用子类特有的方法。
由以上内容可总结出子类转换成父类时的规则:
➢将一个父类的引用指向一个子类对象称为向上转型,系统会自动进行类型转换。
➢此时通过父类引用变量调用的方法是子类覆盖或继承了父类的方法,不是父类的方法。
➢此时通过父类引用变量无法调用子类特有的方法。
前面已经提到,当向上转型发生后,将无法调用子类特有的方法。但是如果需要调用子类特有的方法,可以通过把父类转换为子类来实现。
将个指向子类对象的父类引用赋给一个子类的的引用,即将父类型转换为子类类型,称为向下转型,此时必须进行强制类型转换。
如果Dog类中包含一个接 飞盘的方法catchingFlyDisc(),这个方法是子类特有的,下面的代码就会存在问题。
//Pet为父类, Dog为子类, Pet中包含方法toHospital(),不包含catchingFlyDisc()方法 Pet pet=new Dog();//子类到父类的转换 //会调用Dog类的toHospital()方法,而不是 Pet类的toHospital()方法,体现了多态。 pet.toHospital(); pet.catchingFlyDisc();//无法调用子类特有的方法 12345
可以这样理解,主人可以为任何宠物看病,但只能和狗狗玩接飞盘游戏。在没有断定宠物的确是狗狗时,主人不能与宠物玩接飞盘游戏。因为他需要的是一个宠物,但是没有明确要求是一只狗狗,所以很有可能他的宠物是只小鸟,因此就不能确定是否能玩接飞盘游戏。那么这里需要做的就是进行强制类型转换,将父类转换为子类,然后才能调用子类特有的方法。
Dog dog=(Dog)pet;//将pet转换为Dog类型 dog.catchingFlyDisc();//执行Dog特有的方法 12
上述这种向下转型的操作对接口和抽象(普通)父类同样适用。
向下转型的语法。
<子类型><引用变量名>=(<子类型>父类型的引用变量>; 1 4. instanceof 运算符
在向下转型的过程中,如果不是转换为真实子类类型,会出现类型转换异常。
//Pet为父类,Dog为子类, Bird 为子类 Pet pet = new Dog();//子类到父类的转换 pet.toHospital();//会调用Dog类的toHospital()方法 Bird bird=(Bird)pet;//将pet转换为Bird 类会出错 1234
在Java中提供了 instanceof运算符来进行类型的判断。
示例9
请判断宠物的类型。
关键代码:
public class Test { public static void main(String[] args) { Pet pet = new Bird(); //Pet pet = new Dog); pet.toHospital(); if (pet instanceof Dog) { Dog dog = (Dog) pet; dog.catchingFlyDisc();//执行狗狗特有的方法,即接 飞盘 } else if (pet instanceof Bird) { Bird bird = (Bird) pet; bird.fly();//执行小鸟特有的方法,即飞翔 } } } 1234567891011121314
使用instanceof时,对象的类型必须和instanceof后面的参数所指定的类有继承关系,否则会出现编译错误。例如,代码“pet instanceof String”,会出现编译错误。instanceof通常和强制类型转换结合使用。至此,任务3结束。
从上面的例子不难发现,多态的优势非常突出。
➢可替换性:多态对已存在的代码具有可替换性。
➢可扩充性:多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。
➢接口性:多态是父类向子类提供了一个共同接口,由子类来具体实现。
➢灵活性:多态在应用中体现了灵活多样的操作,提高了使用效率。
➢简化性:多态简化了应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。
在多态的程序设计中,一般有以下两种主要的应用形式。
1.使用父类作为方法的形参使用父类作为方法的形参,是Java中实现和使用多态的主要方式。下面通过示例10进行演示。
示例 10
假如狗、猫、鸭3种动物被一个主人领养, 这个主人可以控制各种动物叫的行为,实现一个主人类,在该类中定义控制动物叫的方法,请实现此功能。
关键代码:
//主人类 public class Test { class Host { public void letCry(Animal animal) { animal.cry();//调用动物叫的方法 } } //以上为主人类代码,以下为调用代码 public class Test { public static void main(String[] args) { Host host = new Host(); Animal animal; animal = new Dog();//控制狗叫 hostletCry(animal); animal = new Cat();//控制猫叫 host.letCry(animal); animal = new Duck();//控制鸭叫 host.letCry(animal); } }
123456789101112131415161718192021在示例10的主人控制动物叫的方法中,并没有把动物的子类作为方法参数,而是使用Animal父类。当调用letCry()方法时,实际传入的参数是一个子类的动物,最终调用的也是这个子类动物的cry()方法。
2.使用父类作为方法的返回值使用父类作为方法的返回值,也是Java中实现和使用多态的主要方式。下面通过示例11进行演示。
示例11
假如这3种动物被一个主人领养,这个主人可以根据其他人的要求任意送出一只宠物,送出的动物可以叫,请实现此功能。
关键代码:
class Host { //赠送动物 public Animal donateAnimal(String type) { Animal animal; if (type == "dog") { animal = new Dog(); } else if (type == "Cat") { animal = new Cat); } else { animal = new Duck(); return animal; } } //以上为主人类代码,以下 为调用代码 public class Test { public static void main(String[] args) { Host host = new Host(); Animal animal; animal = host.donateAnimal("dog"); animal.cry();//狗叫 animal = host.donateAnimal("cat"); animal.cry(); // 猫叫 } }
12345678910111213141516171819202122232425在上述代码中将父类Animal作为赠送动物方法的返回类型,而不是具体的子类,调用者仍然可以控制动物叫,动物叫的行为则由具体的动物类型决定。
相关知识
java 多态
Java笔记:多态polymorphic
Object类、多态
多态使用案例
举例理解java的多态,通俗,易懂
使用多态实现主人领养宠物并与宠物玩耍
编写程序模拟“主人”喂养“宠物”的场景,利用多态的思想!!!
编写程序模拟“主人”喂养“宠物”的场景,利用多态的思想。
宠物的生长(多态)
宠物的生长(虚函数和多态)
网址: 多态 https://m.mcbbbk.com/newsview154808.html
上一篇: = |
下一篇: 贺州市自然资源局国有建设用地使用 |