属性是不存在多态的
案例:
import java.util.*;publicclassDemo{publicstaticvoidmain(String[] args){
Animal a =newDog();
System.out.println(a.name);//动物}}classAnimal{
String name ="动物";//吃publicvoideat(){
System.out.println("动物吃");}//睡publicvoidsleep(){
System.out.println("动物睡");}}classDogextendsAnimal{
String name ="哈士奇";//吃publicvoideat(){
System.out.println("狗吃屎");}//睡publicvoidsleep(){
System.out.println("狗趴着睡");}//加publicvoidshout(){
System.out.println("狗汪汪的叫");}}classShiKeLangextendsAnimal{publicvoidmoveShi(){
System.out.println("移动屎球");}}
引用之间的转换
向上转型
将子类对象的引用赋值给父类类型的引用
案例:
import java.util.*;publicclassDemo{publicstaticvoidmain(String[] args){
Dog d =newDog();
Animal a = d;}}classAnimal{
String name ="动物";//吃publicvoideat(){
System.out.println("动物吃");}//睡publicvoidsleep(){
System.out.println("动物睡");}}classDogextendsAnimal{
String name ="哈士奇";//吃publicvoideat(){
System.out.println("狗吃屎");}//睡publicvoidsleep(){
System.out.println("狗趴着睡");}//加publicvoidshout(){
System.out.println("狗汪汪的叫");}}classShiKeLangextendsAnimal{publicvoidmoveShi(){
System.out.println("移动屎球");}}
向下转型
将父类类型的引用赋值给子类类型的引用
意义:当我们需要用父类的引用去调用子类特有的方法时,需要将父类的引用类型向下转型为子类类型的引用,这时候需要强制转换,结果可能失败 会报类型转换异常
Exception in thread "main" java.lang.ClassCastException: ShiKeLang cannot be cast to Dog at Demo.main(Demo.java:5)
从以上的案例说明:一个对象创建之后 其类型永远不可改变(java中对象类型不可变)
案例:
import java.util.*;publicclassDemo{publicstaticvoidmain(String[] args){
Animal a =newShiKeLang();
Dog d =(Dog)a;
d.shout();}}classAnimal{
String name ="动物";//吃publicvoideat(){
System.out.println("动物吃");}//睡publicvoidsleep(){
System.out.println("动物睡");}}classDogextendsAnimal{
String name ="哈士奇";//吃publicvoideat(){
System.out.println("狗吃屎");}//睡publicvoidsleep(){
System.out.println("狗趴着睡");}//加publicvoidshout(){
System.out.println("狗汪汪的叫");}}classShiKeLangextendsAnimal{publicvoidmoveShi(){
System.out.println("移动屎球");}}
当两个类之间没有继承关系 这两个类引用之间是否可以转换
当两个类之间没有继承关系时 引用类型之间是不可以转换的 即使强制转换 编译也不通过
案例:
import java.util.*;publicclassDemo{publicstaticvoidmain(String[] args){
ShiKeLang s =newShiKeLang();
Dog d =(Dog)s;}}classAnimal{
String name ="动物";//吃publicvoideat(){
System.out.println("动物吃");}//睡publicvoidsleep(){
System.out.println("动物睡");}}classDogextendsAnimal{
String name ="哈士奇";//吃publicvoideat(){
System.out.println("狗吃屎");}//睡publicvoidsleep(){
System.out.println("狗趴着睡");}//加publicvoidshout(){
System.out.println("狗汪汪的叫");}}classShiKeLangextendsAnimal{publicvoidmoveShi(){
System.out.println("移动屎球");}}
instanceof(实例 属于)
作用:能够判断一个引用中所存放的数据类型
语法:
引用名 instanceof 类型
a instanceofDog
值是一个布尔类型
案例:
import java.util.*;publicclassDemo{publicstaticvoidmain(String[] args){
Animal a =newDog();if(a instanceofDog){
Dog d =(Dog)a;
d.shout();}else{
a.eat();
a.sleep();}}}classAnimal{
String name ="动物";//吃publicvoideat(){
System.out.println("动物吃");}//睡publicvoidsleep(){
System.out.println("动物睡");}}classDogextendsAnimal{
String name ="哈士奇";//吃publicvoideat(){
System.out.println("狗吃屎");}//睡publicvoidsleep(){
System.out.println("狗趴着睡");}//加publicvoidshout(){
System.out.println("狗汪汪的叫");}}classShiKeLangextendsAnimal{publicvoidmoveShi(){
System.out.println("移动屎球");}}
案例:
Animal a =newShiKeLang();
System.out.println(a instanceofDog);//false
ShiKeLang a =newShiKeLang();
System.out.println(a instanceofDog);//编译报错
在用instanceof判断之前首先编译器会先进行判断两个类之间是否存在继承关系
关于多态中的特点的口诀
编译看左边:编译时 只能调用引用所对应类中声明的方法
运行看右边:当多态发生时 调用方法执行的是子类覆盖父类后的方法的实现
Animal a = new Dog();
多态的应用
多态用在数组中
定义一个动物类
方法: eat()
每个子类都重写eat方法
狗类
猫类
案例:
publicclassDemo{publicstaticvoidmain(String[] args){//分别创建每个子类的对象 调用吃的方法/*Dog d = new Dog();
Cat c = new Cat();
d.eat();
c.eat();*///数组将这些动物
Animal[] zoo ={newDog(),newCat()};//遍历for(int i =0;i<zoo.length;i++){
zoo[i].eat();}}}classAnimal{//吃publicvoideat(){
System.out.println("动物吃");}}classDogextendsAnimal{publicvoideat(){
System.out.println("狗吃骨头");}}classCatextendsAnimal{publicvoideat(){
System.out.println("猫吃鱼");}}
练习:
有一个动物类的数组 数组中有很多动物对象 统计数组中狗对象的个数
考点:
instanceof
升级:将所有的狗对象放到一个狗窝中(狗的数组)
publicclassDemo{publicstaticvoidmain(String[] args){//分别创建每个子类的对象 调用吃的方法/*Dog d = new Dog();
Cat c = new Cat();*///数组将这些动物
Animal[] zoo ={newDog(),newCat(),newDog(),newCat()};int sum =0;for(int i =0;i<zoo.length;i++){//判断是否为狗if(zoo[i]instanceofDog){
sum++;}}
System.out.println(sum);
Dog[] d =newDog[sum];int j =0;for(int i =0;i<zoo.length;i++){if(zoo[i]instanceofDog){
d[j]=(Dog)zoo[i];
j++;}}}}classAnimal{//吃publicvoideat(){
System.out.println("动物吃");}}classDogextendsAnimal{publicvoideat(){
System.out.println("狗吃骨头");}}classCatextendsAnimal{publicvoideat(){
System.out.println("猫吃鱼");}}
改进之后的案例:
import java.util.*;publicclassDemo{publicstaticvoidmain(String[] args){//分别创建每个子类的对象 调用吃的方法/*Dog d = new Dog();
Cat c = new Cat();*///数组将这些动物
Animal[] zoo ={newDog(),newCat()};
Dog[] d =newDog[0];int j =0;for(int i =0;i<zoo.length;i++){//判断是否为狗if(zoo[i]instanceofDog){
d = Arrays.copyOf(d,d.length+1);
d[j]=(Dog)zoo[i];
j++;}}
System.out.println(d.length);}}
多态用在函数的参数上
案例: 多态可以使函数的功能更加通用
import java.util.*;publicclassDemo{publicstaticvoidmain(String[] args){m(newDog());m(newCat());m(newDuck());}//给我传进一个动物 我会调用这个动物吃的方法 Animal a = new Dog()publicstaticvoidm(Animal a){
a.eat();}}classAnimal{//吃publicvoideat(){
System.out.println("动物吃");}}classDogextendsAnimal{publicvoideat(){
System.out.println("狗吃骨头");}}classCatextendsAnimal{publicvoideat(){
System.out.println("猫吃鱼");}}