Java多态详解

java多态

多态的出现:
  • 父类的引用指向子类的对象
		定义格式:父类类型 变量名 = new 子类类型();
  • 接口的引用指向遵从接口的实现类对象
   		定义格式:接口 变量名 = new 实现类();
多态的作用:
  1. 拓宽方法的参数范围:
 - 参数要求是父类,这里可以传入父类或者其子类的对象

 - 参数是接口类型,这里可以传入直接或者间接的接口实现类对象
  1. 拓宽方法的返回值范围:
- 返回值类型要求是父类,这里可以返回父类或者其子类的对象

- 返回值类型是接口,这里可以返回该接口或该接口的实现类对象
多态的成员特点:
1. 成员变量的特点分析:

 - 当发生多态时,父类的成员变量名和子类相同时, 
 - 我们引用的该成员变量是属于父类还是属于子类的呢?

public class Person {
    public int id = 10;
}

class Student extends Person {
    public int id = 11;
}

class Test {
    public static void main(String[] args) {
    	//多态
        Person person = new Student();
        System.out.println(person.id);
    }
}

System.out.println(person.id);

打印的结果值是10 也就是说这里打印的是父类的成员变量id的值


为了更一步的证明这个结果的正确性,我在Person类的id前加了个static修饰

public class Person {
    public static int id = 10;
}

然后idea对我做出了鄙视:
来自idea的鄙视
这里idea清楚的给出了提示,推荐使用类名直接调用成员变量:也就是用Person.id 调用。也就是说这个id是属于Person类的

这是由于对象自带属性值,变量不会发生Override。下面给出代码证明:
变量的特点
我们可以清楚的看到person对象没有任何的指向,但是在调用属性值时,idea默认的给出了id的属性
虽然没有给person类对象指向,这段代码会报错,但是我们完全可以证明

对象自带属性值,变量不会发生Override。


2. 成员方法的特点分析:

 - 当发生多态时,父类的成员方法名和子类相同时,  
 - 我们引用的该成员方法是属于父类还是属于子类的呢?  
 - 当用static修饰呢?

public class Person {
    
    public void sleep() {
        System.out.println("人睡觉");
    }

    public void read() {
        System.out.println("人阅读");
    }
}

class Student extends Person {

      @Override
    public void sleep() {
        System.out.println("学生睡觉");
    }

    public void read() {
        System.out.println("人阅读");
    }
}

class Test {
    public static void main(String[] args) {
        Person person = new Student();
        person.sleep();
        person.read();
    }
}

person.sleep(); 学生睡觉
person.read(); 人阅读

我们可以清楚的看出:

  • 方法发生重写,在发生多态的时候调用的是子类的同名方法
  • 当没有发生重写的方法被调用时,调用的是父类的同名方法

当然这里idea也给出了我浓浓的鄙视,提示我重名方法加@Override注解(这代表着重写)。
方法重名加注解


那当方法加上了static呢?结果又会怎样呢

public class Person {

    public  static void  sleep() {
        System.out.println("人睡觉");
    }


}

class Student extends Person {
    @Override
    public static void sleep() {
        System.out.println("学生睡觉");
    }
}

class Test {
    public static void main(String[] args) {
        Person person = new Student();
        person.sleep();
    }
}

person.sleep(); ????
这里运行直接报错了!!!

  • Error:(17, 5) java: 方法不会覆盖或实现超类型的方法
  • 也就是说@Override不能生效

那么我们把@Override去了呢?

class Student extends Person {
    public static void sleep() {
        System.out.println("学生睡觉");
    }
}

person.sleep(); 人睡觉

  • 这里打印的是父类的同名方法

idea也给出了鄙视
idea的鄙视
这里idea清楚的给出了提示,推荐使用类名直接调用成员方法:也就是用Person.sleep()调用。也就是说这个sleep()方法是属于Person类的

总结:
当多态发生时,成员方法,没有发生重写访问的就是父类本身的同名方法

多态的转型:
  1. 向上转型:
  • 使用格式:父类类型 变量名=new 子类类型();
    适用场景:当不需要面对子类类型时,通过提高扩展性,或者使用父类的功能就能完成相应的操作。
  1. 向上转型:
  • 使用格式:子类类型 变量名=(子类类型) 父类类型的变量;
  • 适用场景:当要使用子类特有功能时。(这里的父类类型要求是已经向上转型的子类类型,否则可能会出错)
综上所述:

        在用多态时要把握好是否 发生重写,发生重写的访问的是子类的属性,否则访问的是父类的属性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值