Java——多态性

Java多态性

多态是指父类中定义的方法被子类继承之后,可以表现出不同的行为,这使得同一个方法在父类及其各个子类中具有不同的含义。

Java 实现多态有 3 个必要条件:继承、重写和向上转型。

  • 继承:在多态中必须存在有继承关系的子类和父类。
  • 重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
  • 向上转型(父类对象指向子类引用):在多态中需要将子类的引用赋给父类对象,只有这样该引用才既能可以调用父类的方法,又能调用子类的方法。

多态中的成员的访问特点

多态分为编译时多态和运行时多态。其中编译时多态是静态的,主要是指方法的重载,它是根据参数列表的不同来区分不同的方法。通过编译之后会变成两个不同的方法,在运行时谈不上多态。而运行时多态是动态的,它是通过动态绑定来实现的.

看下面的例子:

public class Animal {
    public int age = 3;
    public void eat(){
        System.out.println("动物进食.....");
    }
}
public class Cat  extends  Animal{
    public int age = 2;
    public int weight = 10;
    @Override
    public void eat(){
        System.out.println("猫吃鱼...");
    }
    public void palyGame(){
        System.out.println("猫抓老鼠玩....");
    }
}
public class Dog  extends  Animal{
    public int age = 4;
    public String name = "旺财";
    @Override
    public void eat(){
        System.out.println("狗吃骨头....");
    }
    public void work(){
        System.out.println("狗看家....");
    }
}
public class AnimalTest {
    public static void main(String[] args) {
        // 父类引用指向子类对象
        Animal a1 = new Cat();
        a1.eat();// 猫吃鱼
        //a1.palyGame();//访问不到
        System.out.println(a1.age);//3
        Animal a2 = new Dog();
        a2.eat();//狗吃骨头
        System.out.println(a2.age);//3
    }
}

成员方法:
看左边,看的是父类的引用(看父类中是否具有该成员方法)
看右边,看的是子类的对象(实际运行时的子类重写父类的方法)

成员变量:不具备多态性,只要看引用变量声明的类型即可。

成员方法:编译看左边 运行看右边
成员变量:编译看左边 运行看左边

使用多态的利弊

好处:提高了代码的扩展性。定义方法的时候,使用的是父类型作为参数,在使用是的时候,可以使用具体的子类作为真是的操作对象

弊端:不能访问子类特有的成员。

animal.str = "";    // 编译出错,提示Animal类中没有str属性
animal.eatMethod();    // 编译出错,提示Animal类中没有eatMethod()方法

若想要要调用子类的特有成员,就要使用到对象的转型

((Cat)animal).str = "";    // 编译成功
((Cat)animal).eatMethod();    // 编译成功

对象类型转换:向上转型和向下转型

将一个类型强制转换成另一个类型的过程被称为类型转换。

对象类型转换,是指存在继承关系的对象,不是任意类型的对象。当对不存在继承关系的对象进行强制类型转换时,会抛出 Java 强制类型转换(java.lang.ClassCastException)异常。

Dog dog = new Dog();
Cat cat = (Cat)dog;    // 编译出错,不允许把Dog对象类型转换为Cat对象类型

1)向上转型
父类引用指向子类对象为向上转型,语法格式如下:

fatherClass obj = new sonClass();

其中,fatherClass 是父类名称或接口名称,obj 是创建的对象,sonClass 是子类名称。

向上转型就是把子类对象直接赋给父类引用,不用强制转换。使用向上转型可以调用父类类型中的所有成员,不能调用子类类型中特有成员,最终运行效果看子类的具体实现。
2)向下转型
与向上转型相反,子类对象指向父类引用为向下转型,语法格式如下:

sonClass obj = (sonClass) fatherClass;

其中,fatherClass 是父类名称,obj 是创建的对象,sonClass 是子类名称。

向下转型可以调用子类类型中所有的成员,不过需要注意的是如果父类引用对象指向的是子类对象,那么在向下转型的过程中是安全的,也就是编译是不会出错误。但是如果父类引用对象是父类本身,那么在向下转型的过程中是不安全的,编译不会出错,但是运行时会出现我们开始提到的 Java 强制类型转换异常,一般使用 instanceof 运算符来避免出此类错误。

Animal animal = new Dog();    // 向上转型,把Dog类型转换为Animal类型
Dog dog = (Dog) animal; // 向下转型,把Animal类型转换为Dog类型
Animal animal = new Cat();
if (animal instanceof Cat) {
    Cat cat = (Cat) animal; // 向下转型
    ...
}

instanceof关键字

Java 中可以使用 instanceof 关键字判断一个引用是否为一个类(或接口、抽象类、父类)的实例,返回值为boolean类型,语法格式如下所示。

boolean result = obj instanceof Class
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值