总结:java中的多态

多态

1.发生多态的前提:

前提:子类引用父类的对象

2.向上转型

1.定义:

向上转型:父类引用子类对象----》向上转型是子类对象转成父类对象

2.向上转型发生的时机

(1)直接赋值
Animal animal = new Cat(“大花猫”, 19, “man”);
(2)方法传参
在这里插入图片描述
(3)方法返回

3.代码示例与图解
class Animal {
        public String name;
        public int age;

//    public Animal() {
//    }

        static {
            System.out.println("Animal::static{}");
        }

    {
        System.out.println("Animal::instance{}");
    }

    public Animal(String name, int age) {
    **eat();  //构造方法内部可以发生多态** 
        this.name = name;
        this.age = age;
    }

    public void eat() {
        System.out.println("Animal: eat()");
    }
}

class Cat extends Animal {
    public String sex;

    static {
        System.out.println("cat::static{}");
    }

    {
        System.out.println("cat::instance{}");
    }

    public Cat(String name, int age, String sex) {
        super(name, age);
        this.sex = sex;
    }

    @Override
    public void eat() {
        System.out.println("Cat :: eat()");
    }

    public void run() {
        System.out.println("Cat :: run()");
    }
}
  //向上转型
    public static void main(String[] args) {
        Animal animal = new Cat("大花猫", 19, "man");**//父类引用子类对象**
        animal.eat();
    }

3.动态绑定

1.定义:

定义:父类引用子类对象,并且父类和子类有同名的覆盖方法;这时,如果通过父类引用调用这个重名方法,就会发生动态绑定。

2.代码示例与图解
class Animal {
        public String name;
        public int age;
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void eat() {
        System.out.println("Animal: eat()");
    }
}

class Cat extends Animal {
    public String sex;
    public Cat(String name, int age, String sex) {
        super(name, age);
        this.sex = sex;
    }

    @Override
    public void eat() {
        System.out.println("Cat :: eat()");
    }

    public void run() {
        System.out.println("Cat :: run()");
    }
}

 public static void main(String[] args) {
        Animal animal = new Cat("大花猫", 19, "man");//父类引用子类对象
        animal.eat();
    }
运行结果如下:![在这里插入图片描述](https://img-blog.csdnimg.cn/20191102170019314.png)

4.方法的重写(Override)

1.定义

定义:子类实现父类的同名方法, 并且参数的类型和个数完全相同, 这种情况称为 覆写/重写/覆盖(Override).

2.注意事项

(1)方法名相同、返回值相同(可以不同,但是返回值之间需要构成协变类型)、参数列表相同;
(2)不能在同一个类当中。
(3) 普通方法可以重写, static 修饰的静态方法不能重写。
(4)重写中子类的方法的访问权限不能低于父类的方法访问权限。
(5)重写方法时显式加上 @Override 注解。

5.重写与重载的区别

6.多态的深入理解

1.使用多态的优点

(1)类调用者对类的使用成本进一步降低
(2) 能够降低代码的 “圈复杂度”, 避免使用大量的 if - else
(3)可扩展能力更强

2.对多态的概述

父类引用子类对象,并且父类和子类有同名的覆盖方法;这时,如果通过父类引用调用这个重名方法,就会发生动态绑定。

3.代码示例
class Shape {
    public void draw() {
    }
}

class Cycle extends Shape {
    @Override
    public void draw() {
        System.out.println("画圆");
    }
}

class Rect extends Shape {
    @Override
    public void draw() {
        System.out.println("画矩形");
    }
}

public class TestDemo2 {
    public static void drawMap(Shape shape) {
        shape.draw();
    }

    public static void main(String[] args) {
        Shape shape = new Cycle();
        Shape shape1 = new Rect();
        drawMap(shape);
        drawMap(shape1);
    }
}

7.向下转型

1.定义

向下转型就是父类对象转成子类对象;

2.确认向下转型是否安全操作

instanceof 可以判定一个引用是否是某个类的实例. 如果是, 则返回 true. 这时再进行向下转型就比较安全了

class Animal {
        public String name;
        public int age;

//    public Animal() {
//    }

        static {
            System.out.println("Animal::static{}");
        }

    {
        System.out.println("Animal::instance{}");
    }

    public Animal(String name, int age) {
        **eat();  //构造方法内部可以发生多态**
        this.name = name;
        this.age = age;
    }

    public void eat() {
        System.out.println("Animal: eat()");
    }
}

class Cat extends Animal {
    public String sex;

    static {
        System.out.println("cat::static{}");
    }

    {
        System.out.println("cat::instance{}");
    }

    public Cat(String name, int age, String sex) {
        super(name, age);
        this.sex = sex;
    }

    @Override
    public void eat() {
        System.out.println("Cat :: eat()");
    }

    public void run() {
        System.out.println("Cat :: run()");
    }
}
class Bird extends Animal {
    public Bird(String name, int age) {
        super(name, age);
    }
    public void fly() {
        System.out.println("Bird :: fly()");
    }
}
public class TestDemo1 {
    public static void main(String[] args) {
        Animal animal = new Bird("小鸟", 19);
        ***//向下转型->一定要发生向上转型->instanceof:***
        if (animal instanceof Cat) {    ***//cat是否是animal的实例***
            Cat cat = (Cat) animal;     ***//java.lang.ClassCastException---类型转换异常***
            cat.run();
        }
    }

    //向下转型
    public static void main(String[] args) {
        //向上转型
        Animal animal = new Cat("caocao", 19, "man");
        //向下转型
        Cat cat = (Cat) animal;
        cat.run();
    }
}

8.super关键字的使用

(1)子类调用父类的方法:super.func();
(2)子类调用父类的属性:super.data;
(3)子类调用父类的构造方法:super();必须放在第一行;
子类的构造,首先需要构造父类;

9.super与this的区别

1.this关键字(还可参考:https://www.cnblogs.com/newbie27/p/10437587.html)

(1.)每个类的每个非静态方法(没有被static修饰)都会隐含一个this关键字,它指向调用这个方法的对象;当在方法中使用本类属性时,都会隐含地使用this关键字,当然也可以明确使用。
this可以看成是一个变量,它的值就是当前对象的引用;
this关键字只能在方法内部使用,表示对“调用方法的那个对象”的引用,如果是在同一类中调用另外一个方法,则可以不用写this,直接调用;
(2.)为了区分属性和局部变量,可以通过this关键字来调用;
(3.)this关键字的用法:
当类中非静态方法的参数名与类的某个成员变量名相同时,为了避免参数作用范围覆盖了成员变量的作用范围,必须明确使用this关键字来指定;
如果某个构造方法的第一条语句具有形式this(…),那么这个构造方法将调用本类中的其他构造方法;
如果某个方法需要传入当前对象,则可以将当前的对象作为参数传递给它;

2.super关键字

super代表了父类空间的引用

(1.)super的作用:

子父类存在着同名的成员时,在子类中默认时访问子类的成员,可以通过super关键字指定访问父类的成员;
创建子类对象时,默认会先调用父类无参的构造方法,可以通过super关键字指定调用父类的构造方法;

(2.)super的用法

super可以用来引用直接父类的实例变量。
super可以用来调用直接父类方法。
super()可以用于调用直接父类构造函数

(3.)注意事项:

如果在子类的构造方法上没有指定调用父类的构造方法,java编译器会在子类的构造器里面加上super()语句;
super关键字调用父类的构造函数时,该语句必须要是子类构造函数的第一个语句;
super和this不能同时出现在同一个构造函数中调用其他的构造函数,因为两个语句都要是第一个语句;

3.this和super的区别
(1.)代表的事物不同

super代表的是父类空间的引用;
this代表的是所属函数的调用者对象;

(2.)使用前提不同

super必须要有继承关系才能使用;
this不需要继承关系也能使用;

(3.)调用的构造函数不同

super:调用父类的构造函数;
this:调用所属类的构造函数;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值