理解多态知识--Java

举报
游离 发表于 2023/02/23 19:11:34 2023/02/23
【摘要】 什么是多态?多态(polymorphism)就是多种形态,简单来说就是做同一件事情,不同的对象做就会有不一样的结果/状态或者说就是一个引用调用同一个方法,表示出不一样的行为就叫做多态多态的实现条件1、完成向上转型2、实现方法的重写3、通过引用调用重写向上转型向上转型就是将子类赋值给父类class Animal{ private String name; private int...

什么是多态?

多态(polymorphism)就是多种形态,简单来说就是做同一件事情,不同的对象做就会有不一样的结果/状态

或者说就是一个引用调用同一个方法,表示出不一样的行为就叫做多态

多态的实现条件

1、完成向上转型

2、实现方法的重写

3、通过引用调用重写

向上转型

向上转型就是将子类赋值给父类

class Animal{
    private  String name;
    private  int age;

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void eat() {
        System.out.println(name+"正在吃饭");
    }
    @Override
    public String toString() {
        return "Animal{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

}

class Dog extends Animal{
    public String tail;
    public Dog(String name, int age) {
        super(name, age);
    }

    public void bark() {
        System.out.println(getName()+"正在旺旺叫");
    }
    @Override
     public void eat() {    //重写
        System.out.println(getName()+"要吃狗粮");
    }
}

public class test {
    public static void main(String[] args) {
        //父类引用  引用了子类的对象
        Animal animal = new Dog("旺财", 2);//向上转型,将子类赋值给父类
        animal.bark;//err
        animal.tail;//err
        //向上转型之后通过父类引用 调用自己的方法,不能调用子类的成员变量和方法
       
         animal.eat();//在子类里面添加一个与父类一样的eat方法,就会变成重写,打印的就是就会是子类的eat方法
    }
    //animal.eat();是动态绑定,事实上,在编译的时候会调用Animal类,但是运行的时候会调用Dog类
复制代码

重写

什么是重写?

重写也叫覆盖 或者 覆写,在方法相同的基础上完成更加个性化的功能

重写需要的条件

1、方法名要相同

2、方法的返回值相同,要是子类与父类的返回值也是父子类的关系,也是可以算作是重写的【协变类型】

3、方法的参数列表相同【个数、类型、顺序】

4、父类中static的方法不能被重写

5、父类中private修饰方法不能被重写

6、子类的访问权限修饰符,需要大于等于父类的访问修饰限定符

访问权限:private <default <protected <public

协变类型

子类与父类的返回值也是父子类的关系

//父类:
public Animal eat() {
    System.out.println(name+"正在吃饭");
    return  new Animal("haha",12);
}
//子类:
 @Override
    public Dog eat() {
        System.out.println(getName()+"要吃狗粮");
        return new Dog("haha", 23);
    }
复制代码

加上final就可以使父类中的方法不能被重写--->密封方法

重载与重写

重载就是参数列表【参数个数 类型 顺序】会有一定的变化

在不考虑协变类型的情况下,重写就是方法名 返回值 参数列表都一样

也就是说,方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现。

重写的设计原则

对于已经投入使用的类(父类),尽量不要进行修改。最好的方式是:重新定义一个新的类(子类),来重复利用其中共性的内容,并且添加或者改动新的内容。

向上转型的3种方式

public class test {
    public static void func1(Animal animal) {   //方法二:方法的传参

    }

    public static Animal func2() {         //方法三:方法的返回值
            return new Dog("旺财", 2);
    }
    public static void main(String[] args) {
        Dog dog = new Dog("旺财", 2);
        func1(dog);//方法二  传参
    }
    public static void main2(String[] args) {
        //父类引用  引用了子类的对象
        Animal animal = new Dog("旺财", 2);//向上转型,将子类赋值给父类---方法一:直接赋值
        animal.eat();//通过引用调用重写
        //animal.bark;
        //animal.tail;
    }
复制代码

多态的具体实现

class Animal{
    private  String name;
    private  int age;

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void eat() {
        System.out.println(name+"正在吃饭");
    }
    @Override
    public String toString() {
        return "Animal{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

}

class Dog extends Animal{
    public String tail;
    public Dog(String name, int age) {
        super(name, age);
    }

    public void bark() {
        System.out.println(getName()+"正在旺旺叫");
    }
    @Override
    public void eat() {  //重写
        System.out.println(getName()+"要吃狗粮");
    }
}

class Bird extends  Animal {

    public Bird(String name, int age) {
        super(name, age);
    }

    @Override
    public void  eat() {   //重写
        System.out.println(getName()+"正在吃鸟粮");
    }
}
public class test {
    public static void func1(Animal animal) {   //向上转型
            animal.eat(); //首先,这是一个动态绑定,其次,传过来的对象不同,就会调用不同的eat方法,这就是多态 
   						//一个引用调用同一个方法,表示出不一样的行为就叫做多态
    }

    public static void main(String[] args) {
        func1(new Dog("旺财", 1));
        func1(new Bird("小鸟", 3));
    }
}
//结果:
//旺财要吃狗粮
//小鸟正在吃鸟粮
复制代码

另外一种多态实现

package TestDemo1;
class  Shape{
    //属性……
    public void draw() {
        System.out.println("画一个图形");
    }
}

class  Triangle  extends  Shape{
    //因为父类Shape没有构造方法,所以就不用谢super完成构造方法了
    @Override      //重写
    public void draw() {
        System.out.println("△");
    }
}

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

public class Test1 {
    public static void  func(Shape shape){  //记得加上static
        shape.draw();
    }

    public static void main(String[] args) {
        Triangle triangle = new Triangle();
        func(triangle);
        Cycle cycle = new Cycle();
        func(cycle);
    }
}
//△
//○
复制代码

多态确实是十分奇妙的一种语法。如有错误,还请大家多多指正。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。