Java多态&抽象类

回顾

继承:对共性的抽取,实现对代码的复用。
is a 的关系 例如:Dog is an Animal;
this super 构造方法的使用
面向对象三大特性:封装 继承 多态

多态

去完成某个行为,不同的对象会产生不同的结果
同一件事情,发生在不同对象身上,就会产生不同的结果。

多态实现的条件

必须存在:向上转型(把子类对象给父类) ,重写,继承

1.必须在继承体系下
2.子类必须要对父类中的方法进行重写
3.通过父类的引用调用重写的方法

例:

向上转型

向上转型1(直接赋值)在这里插入图片描述
建立在继承关系上
在这里插入图片描述
在这里插入图片描述

问题:为什么无法访问这个方法?

在这里插入图片描述
答:当我们发生向上转型时,只能通过父类的引用访问父类特有的方法,无法访问子类的特性

向上转型2(方法的传参)
在这里插入图片描述
向上转型3(方法的返回值)
在这里插入图片描述

重写(override) | 重载

1.方法名称相同

2.方法所含参数相同 |(不同)

3.方法返回值相同

例:
在这里插入图片描述
引入:@Override(重写的注解)这个注解的意思是当前代码是被重写的,如果有问题则报错
在这里插入图片描述
重写正常则不报错
在这里插入图片描述
也可通过编译器自动生成
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

动态绑定

1.向上转型
优点:使代码更加灵活
缺点:不能够访问到子类中特有的属性/方法
在这里插入图片描述

2.重写
在这里插入图片描述

3.通过父类的调用访问子类当中和父类同名的方法
在这里插入图片描述
通过查看字节码文件发现,确实和我们猜测一样,调用父类的eat()方法
编译时与运行时不一样(可以理解为运行时候帮我们调用了重写)多态的基础
在这里插入图片描述

提问:有没有静态绑定?

例如:重载1.方法名相同2.返回值相同3.包含参数不同
在编译的时候我已经知道了应该调用哪个方法

重写需要注意的点

1.当父类中的方法被private修饰时是无法进行重写的

在这里插入图片描述

2.static 修饰的方法是不能重写的(静态方法)

在这里插入图片描述

3.子类的修饰权限要大于或者等于父类的修饰权限

在这里插入图片描述
权限大小:private<默认权限/包访问权限<protected<public

4.当父类中的方法被final修饰时是无法进行重写的(此时这个方法被称为密封方法)

在这里插入图片描述

5.父类构造方法不可以重写

重写和重载的区别

在这里插入图片描述

多态

对于方法中的Animal 参数 他不知自己将来会调用那个对象
但我们知道:当调用哪个对象的时候就会调用它相对应的eat方法

从而知道 当父类引用引用的对象不一样的时候,表现出来的行为也是不一样的
我们就把他叫做多态!!!

在这里插入图片描述

多态优缺点的感受:

优点:
1.降低代码的圈复杂度(一般不超过10),避免使用大量的if --else
2.可扩展能力强 如果需要新的东西 加就好了再定义一个新的类的实力

缺陷:代码运行效率降低
1.属性没有多态性
2.构造方法没有多态性

例:画图形

class Shape {
    public void draw() {
        System.out.println("画图形!");
    }
}
class Rect extends Shape {
    @Override
    public void draw() {
        System.out.println("画矩形!");
    }
}
class Cycle extends Shape {
    @Override
    public void draw() {
        System.out.println("画圆形! ");
    }
}
class Flower extends Shape {
    @Override
    public void draw() {
        System.out.println("❀!");
    }
}
public class Test3 {
    public static void drawMap(Shape sh1) {
        sh1.draw();
    }
    public static void main(String[] args) {
        Shape shape1 = new Rect();
        drawMap(shape1);

        System.out.println("==============");

        Shape shape2 = new Cycle();
        drawMap(shape2);

        System.out.println("==============");

        drawMap(new Flower());
    }
}

注意:当在父类的构造方法中调用父类与子类重写的方法,会执行子类的方法!!!

例:

    class B {
        public B() {
            func();// 以后不要这样写 !!
        }
        public void func() {
            System.out.println("B.func()");
        }
    }
    class D extends B {
        private int num = 1;

        public D() {
            super();
        }

        @Override
        public void func() {
            //System.out.println("fafdadssa!!!!!");
            System.out.println("D.func() " + num + " 因为父类此时还没有走完!");
        }
    }
    public class Test4 {
        public static void main(String[] args) {
            D d = new D();
        }
    }

向下转型:

在这里插入图片描述

向下转型非常不安全

在这里插入图片描述

可以通过if语句和instanceof关键字来判断是否满足需要

抽象类

面向对象的概念中,所有的对象都是用类来描绘的,但是反过来,并不是所有类都是用来描述对象的,如果一个类中没有足够的信息来描绘一个对象,就叫做抽象类。

问题:抽象类和普通类有什么区别?
1.抽象类不能实例化 普通类可以
2.抽象类当中可以包含非抽象方法和抽象方法,但普通类只能包含非抽象方法
3.抽象类也是类可以包含普通成员变量/方法/构造方法

抽象类的特性

1.通过abstract 关键字来修饰类

2.抽象类不能被实例化

在这里插入图片描述

3.此时在抽象类当中可以有抽象方法或者非抽象方法

4.什么是抽象方法(一个方法被abstract修饰,没有具体内容,只要包含抽象方法,那么这个类一定是抽象类)

在这里插入图片描述

5.当一个普通类继承了抽象类,那么必须重写抽象类中的抽象方法,否则会编译报错

在这里插入图片描述

6.抽象类就是用来被继承的,也可以有自己的成员变量,成员方法,与其它类一样

8987b6.png)

7.抽象方法不能被private ,final,static修饰

8.当一个子类没有重写抽象的父类的方法,可以把当前子类变为abstra修饰

9.当这个类再被继承时,一定要去重写抽象方法,否则子类也是抽象类,继续用abstract修饰

10.抽象类当中不一定包含抽象方法

在这里插入图片描述

11.抽象类可以有构造方法,供子类在创建对象时,先初始化父类的对象。

抽象类的作用:

本身不能被实例化,只能创建出该抽象类的子类,然后让子类去重写出抽象类的抽象方法。相当于多了一重编译器的检验,其次实际工作由子类完成。当不小心用成父类了,普通编译器是不会报错的,但抽象类在实例化对象时会报错,帮助我们尽快发现问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值