理解多态知识--Java

2023-01-13 14:18:29 浏览数 (2)

什么是多态?

多态(polymorphism)就是多种形态,简单来说就是做同一件事情,不同的对象做就会有不一样的结果/状态 或者说就是一个引用调用同一个方法,表示出不一样的行为就叫做多态

多态的实现条件

1、完成向上转型 2、实现方法的重写 3、通过引用调用重写

向上转型

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

代码语言:javascript复制
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

协变类型

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

代码语言:javascript复制
//父类:
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种方式

代码语言:javascript复制
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;
    }

多态的具体实现

代码语言:javascript复制
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));
    }
}
//结果:
//旺财要吃狗粮
//小鸟正在吃鸟粮

另外一种多态实现

代码语言:javascript复制
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);
    }
}
//△
//○

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

0 人点赞