首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【Java】面向对象的特征之一(下):多态

【Java】面向对象的特征之一(下):多态

作者头像
喜欢做梦
发布2024-11-25 18:04:02
发布2024-11-25 18:04:02
8430
举报
文章被收录于专栏:学习学习

多态

1.什么是多态?

多态:多种形态,就是去完成某个行为,不同对象去完成时会产生不同的状态。

2.多态的实现条件

  1. 必须在继承体系下(继承);
  2. 子类必须要对父类中的方法进行重写(重写);
  3. 通过父类的引用调用重写的方法(向上转型)。

多态体现:当代码运行时,当传递不同类对象时,会调用对应类中的方法。

可能刚开始看这张图片不是很能理解,接下来会进行对向上转型和重写的讲解,看完在回头看这张代码,我相信你能更清晰的理解他们。

3.多态的优缺点

优点:

  • 能够降低代码的“圈复杂度”,避免大量使用if—else
  • 扩展能力强,改动成本低

缺点:

  • 代码的运行效率低

向上转型和向下转型

向上转型

1.向上转型的理解

向上转型:实际就是创建一个子类对象,将其当成父类对象来使用

2.向上转型格式

父类类型 对象名 =new 子类类型

3.向上转型的实现方式

1.直接赋值
代码语言:javascript
复制
public class Test {
    public static void main(String[] args) {
        Animal animal=new Dog(2,"小乖");      
    }
2.方法的传参
代码语言:javascript
复制
public static void main(String[] args) {
        Dog dog = new Dog(2,"小乖");
        func(dog);
    }
    public static void func(Animal animal){
    }
3.返回值
代码语言:javascript
复制
public static void main(String[] args) {
        Animal animal=func2();
    }
    public static Animal func2(){
        Dog dog = new Dog(2,"小乖");
        return dog;
    }

4.向上转型的优缺点

优点:让代码实现更简单灵活;

缺点:通过父类的引用,调用父类是无法直接调用的,只能调用父类自己的。

向下转型

1.向下转型的理解

向下转型:将父类引用在还原为子类对象

2.向下转型的格式

子类类型 类型名=(子类类型)父类类型名;

3.向下转型的实现方式

先通过向上转型,在进行强制类型转换

由上述代码,可以得出,向上转型是向下转型的基础

如果我在加一个父类的子类猫类。先将狗向上转型为动物,再将其向下转型为猫类,这样是否可以?

结果告诉我们不是所有的向下转型都可以的

上面两种的区别就是,一个本身就是Dog,而另一个是Dog不是Cat。

为了预防这种情况,我们可以使用instanceof来验证

instanceof是引用的意思

代码语言:javascript
复制
    public static void main(String[] args) {
        Animal animal1=new Dog(3,"小黄");
        if(animal1 instanceof Cat){
            System.out.println("引用了猫");
        }
        else{
            System.out.println("没有引用");
        }

重写

1.重写的概念

重写:也称为覆盖。重写是子类对父类非静态、非private修饰,非final修饰,非构造方法等的实现过程进行重新编写。可以理解为子类对父类方法的覆盖。

2.重写的作用

  • 子类能够根据需要实现父类的方法

3.重写的格式

  1. 子类和父类的两个方法名相同;
  2. 子类和父类的参数列表相同(个数,顺序,类型);
  3. 子类和父类的返回值要相同;

如果我们调用animal的fun,其结果又是什么?

我们发现他调用的是子类的重写的方法,这种叫做动态绑定。

什么是动态绑定?

动态绑定:在继承的情况下,当代码运行的时候,通过父类引用,调用父类和子类的重写的方法,结果实际调用了子类的方法

注意事项:

  • 虽然说,重写的时候,子类和父类的方法返回值类型、方法名、参数列表要完全一致,但是被重写的方法返回值类型也可以不同,但是其返回值类型要保持父子关系

既然有了动态绑定,那么应该也有静态绑定吧。

什么是静态绑定?

静态绑定:也称为前期绑定(早绑定),即在编译时,根据用户所传递实参类型就确定了具体调用方法。典型代表函数重载。

代码语言:javascript
复制
    public static void main(String[] args) {
        int a=1;
        int b=2;
        int c=3;
        int ret=add(a,b);
        System.out.println(ret);//3
    }
    public static int add(int a,int b){
       return a+b;
    }
    public static int add(int a,int b,int c){
        return a+b+c;
    }

调用几个参数,你就知道用确定了调用的是那个方法

  • 重写的时候,可以使用@Override注解来起提示作用,如果你的重写方法是错的,那么编译器会报错;注意这里的@Override是写在子类重写父类的方法上面,而不是父类方法上方。
  • 在重写中,子类的重写方法的访问权限不能比父类中被重写的方法,并且不能使用private访问权限符。如果你在子类的访问权限符是protected,而父类却是public,那么将会报错,可以将public改成比protected访问权限低的default。
  • 不能被final修饰,如果被final修饰,这意味着该父类不能被重写(密封方法)
  • 不能使用静态方法

4.重写与重载的区别

所以方法重载是一个类的多态性表现,而方法重写是子类和父类的一种多态性表现。

什么时候使用重写?

对于已经投入使用的类,进行不要修改。最好的方式就是:重新定义一个新的类,来重复利用其中共性的内容并添加或改动新的内容。例如:软件的功能的改进,我们不在原来老的类进行改进,因为原来的软件,用户还在使用。于是我们新建一个类,对这个改进的方面进行重写就好了

5.避免在构造方法中调用重写方法

为什么这么说呢?

1.首先我构建了一个父类Animal和子类Dog,在父类和子类写了fun()重写方法并在父类的构造方法中调用了子类和父类的重写方法。实例化后,我得出的结果是父类的被重写方法还是子类对父类的重写方法?我在父类的构造方法中调用父类的方法,结果应该是调用父类的方法吧。

但结果是子类的构造方法

2.既然我都知道了,在父类构造方法中调用子类和父类的重写方法会发生动态绑定,调用的是子类的重写方法,那么我将子类的代码修改成下面的代码

代码语言:javascript
复制
public class Dog extends Animal{
    int num=1;
   public void fun() {
         System.out.println(num);
    }
}

其实例化后结果会是什么?1吗?

但结果是0,为什么?

这就考察到了代码块的顺序,我们知道代码块的顺序是先执行父类和子类静态代码块顺序,在父类的实例和构造在子类的实例和构造。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-07-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 多态
    • 1.什么是多态?
    • 2.多态的实现条件
    • 3.多态的优缺点
  • 向上转型和向下转型
    • 向上转型
    • 1.向上转型的理解
    • 2.向上转型格式
    • 3.向上转型的实现方式
      • 1.直接赋值
      • 2.方法的传参
      • 3.返回值
    • 4.向上转型的优缺点
    • 向下转型
    • 1.向下转型的理解
    • 2.向下转型的格式
    • 3.向下转型的实现方式
  • 重写
    • 1.重写的概念
    • 2.重写的作用
    • 3.重写的格式
      • 什么是动态绑定?
      • 什么是静态绑定?
    • 4.重写与重载的区别
    • 5.避免在构造方法中调用重写方法
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档