面向对象特征之三:多态性

一、面向对象特征之三:多态性

1、多态性:父类的引用指向子类对象;

              Person p1=new Man();             多态      

          (父类)      (子类)

               容量小        容量大

         相当于double    相当于int

如上总结归纳:多态性中,创建实体后,不能调用子类中存在而父类中不存在的方法。调用的方法必须是子类重写父类的方法。

2、面向对象的第三个特性:多态性;

  2-1、多态性指的是什么?

            多态性可理解为一个事物的多种表现形式。

        1)、方法的重载与重写; 2)、子类对象的多态性

  2-2、子类对象多态性使用的前提:(1)、要有类的继承;(2)、要有子类对父类方法的重写

3、程序运行分为编译状态和运行状态:

             (1)、对于多态性来说,编译时,"看左边",将此引用变量理解为父类的类型

            (2)、运行时,"看右边",关注于真正对象的实体,子类的对象。那么执行的方法就是子类重写父类的方法。

   (在多态性中,创建实体后,不能调用子类中存在而父类中不存在的方法。必须调用的是子类重写父类的方法。)

子类对象的多态性只适用于方法,不适用于属性。

(如:Person类中定义了一个int型的id为1002;person的子类Man中也定义了int型的id为1002;在测试类中main方法中有语句:Person p1=new Man();  System.out.println(p1.id);    此返回值为输出1002;因为多态针对的是对象,类中的属性不可以多态。)

当多态语句 Person p1=new Man();  之后要调用p1.属性,无论什么情况调用的都是多态语句赋值号左边的类中的对应属性。  

4、上转型与下转型:

4-1、向上转型:制造的子类对象赋给父类;

4-2如下面的程序实例:如果希望p1和p2可以调用see()方法,需要向下转型(类似C语言的强制类型转换)。

Person p2=new Woman();

p2.eat();    p2.walk();

//     p2.see();   不能调用(因为see()方法是子类Woman特有的,在父类中不存在。)

Woman w1=(Woman)p2; //向下转型(类似于C语言的强转)

图解:

             

  1. instanceof关键字:

格式: 对象a instanceof A

解释:判断对象a是否是类A的一个实例。是的话返回true;否则false。

实例演示:

if(p1 instanceof Woman) {   //判断p1是否是一个Woman类型。

    Woman w2=(Woman)p1;    //如果p1是Woman类型则用Woman强转

            w2.see();

}

6、有多态情况下的参数为父类类型的参数传递问题:

Public void show(Person p){     }

没有多态的话调用show()方法时,传参数只能传递Person类型的;而有了多态后,可以传递Person类型的子类的参数。即形参列表中可以传递Person类的参数或Person类的子类的参数。

如果没有多态性

            public void show(Person p) {      }

            public void show(Woman w) {             }

            public void show(Man m) {          }

            以上这三个调用会有各自的形参传递;

            但有了多态性后一个带有Person类型形参的就可以实现以上三个,因为Woman和Man都是Person类的子类。

二、代码实例解析:

1、Person类(父类):

package com.atguigu.duotai;



public class Person {

    private String name;

    private int age;

    //有参的构造方法

    public Person(String name, int age) {

        super();

        this.name = name;

        this.age = age;

    }

    public Person() {  //无参的构造方法

        super();

    }



    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 walk() {

        System.out.println("人走路");

    }

    public void eat() {

        System.out.println("人吃饭");

    }

}

2、Woman类(第一个子类):

package com.atguigu.duotai;



public class Woman extends Person{

    private boolean isBeauty;

    //getters和setters方法

    public boolean isBeauty() {

        return isBeauty;

    }

    public void setBeauty(boolean isBeauty) {

        this.isBeauty = isBeauty;

    }

    public Woman() {

        super();

    }

    public Woman(boolean isBeauty) {

        super();

        this.isBeauty = isBeauty;

    }

    //重写自定义方法

    public void walk() {

        System.out.println("女窈窕的走路");

    }

    public void eat() {

        System.out.println("小口吃饭");

    }

    public void see() {

        System.out.println(this.getName()+"今年"+this.getAge()+"岁了");

    }

}

3、Man类(第二个子类):

package com.atguigu.duotai;



public class Man extends Person{

    private boolean smoking;



    public boolean Smoking() {

        return smoking;

    }

    public void setSmoking(boolean smoking) {

        this.smoking = smoking;

    }

    //有参的构造方法

    public Man( boolean smoking) {

        super();

        this.smoking = smoking;

    }

    //无参的构造方法

    public Man() {

        super();

    }

    //重写从父类继承的方法;

    public void walk() {

        System.out.println("男儿走路,不低头");

    }

    public void eat() {

        System.out.println("男-大口吃饭");

    }

    public void see() {

        System.out.println(this.getName()+"看到了很多健身器材");

    }

}

4、TestPerson类(测试类):

package com.atguigu.duotai;

/*

 * 面向对象的第三个特性:多态性;

 * 1、多态性指的是什么?

 *      多态性可理解为一个事物的多种表现形式。

 *   1)、方法的重载与重写; 2)、子类对象的多态性

 * 2、子类对象多态性使用的前提:(1)、要有类的继承;(2)、要有子类对父类方法的重写

 * 3、程序运行分为编译状态和运行状态

 *      对于多态性来说,编译时,"看左边",将此引用变量理解为父类的类型

 *      运行时,"看右边",关注于真正对象的实体,子类的对象。那么执行的方法就是子类重写父类的方法。

 * (在多态性中,创建实体后,不能调用子类中存在而父类中不存在的方法。必须调用的是子类重写父类的方法。)

 * */

public class TestPerson {

    public static void main(String[] args) {

        Person p=new Person();

        p.eat();

        p.walk();

       

        Man m=new Man();

        m.eat();

        m.walk();

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

//      new Man().eat();       也可以运行出结果

//      new Man().walk();

       

        //子类对象的多态性:父类的引用指向子类对象

        Person p1=new Man();   //向上转型

        p1.eat();  p1.walk(); //以左为虚拟方法调用,

//      通过父类的引用指向子类的对象实体,

//      当调用方法时实际执行的必须是子类重写父类的方法;

//      不可以调用子类中存在而父类中没有的方法

//      p1.see();      不能调用(因为see()方法是子类Man特有的,在父类中不存在。)

       

        Person p2=new Woman();     //

        p2.eat();  p2.walk();

//      p2.see();      不能调用(因为see()方法是子类Woman特有的,在父类中不存在。)

        Woman w1=(Woman)p2; //向下转型(类似于C语言的强转),使用强转符。

        w1.see();  //强转后就可以调用see()方法了

       

//      /*

//      * 错误:java.lang.ClassCastException

//      * */

//      Woman w2=(Woman)p1;     不可以将Man类型强转为Woman类型,因为二者都是Person的子类。

//      w2.see();

       

//      Woman w2=(Woman)new Man();

       

        //instanceof:

//      格式: 对象a instanceof 类A 解释:判断对象a是否是类A的一个实例。是的话返回true;否则false。

        if(p1 instanceof Woman) {  //判断p1是否是一个Woman类型。

            Woman w2=(Woman)p1;    //如果p1是Woman类型则用Woman强转

            w2.see();

        }

        if(p1 instanceof Man) {       //判断p1是否是一个Man类型的。

            Man m1=(Man)p1;    //如果p1是Man类型的则强转。

            m1.see();

        }

        if(p1 instanceof Person) {

            System.out.println("Hello world!");

        }

    }

}

运行结果如下:

人吃饭

人走路

男-大口吃饭

男儿走路,不低头

**********

男-大口吃饭

男儿走路,不低头

小口吃饭

女窈窕的走路

null今年0岁了

null看到了很多健身器材

Hello world!

三、多态性的一个使用:

package com.atguigu.duotai;

//多态使用的一个类子

public class TestAnimal {

    public static void main(String[] args) {

        TestAnimal t=new TestAnimal();

        t.func(new Animal());

        t.func(new Dog());       //因为有了多态性所以形参内用Animal的子类也行。

        t.func(new Cat());

    }

    public void func(Animal a) {//包括了:(1)、public void func(Dog a) {   }  和public void func(Cat a) {   }

        a.eat();

        a.jump();

       

        //还可以用强转

        if(a instanceof Dog) {

            Dog d=(Dog)a;

            ((Dog) a).say();

//          d.say();       二者结果相同;

        }

        if(a instanceof Cat) {

            Cat c=(Cat)a;

            ((Cat) a).catchMouse();

//          c.catchMouse();

        }

    }

}

class Animal{

    String name;

    int age;

   

    public void eat() {

        System.out.println("进食");

    }

    public void jump() {

        System.out.println("Jump");

    }

}

class Dog extends Animal{

    public void eat() {

        System.out.println("吃狗食");

    }

    public void jump() {

        System.out.println("Dog Jump");

    }

    public void say() {

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

    }

}

class Cat extends Animal{

    public void eat() {

        System.out.println("吃猫食");

    }

    public void jump() {

        System.out.println("Cat Jump");

    }

    public void catchMouse() {

        System.out.println("猫抓鱼");

    }

}

四、多态的使用练习1:

结果如下所示:

四、多态的使用练习2:

1、GeometricObject类(父类):

package com.atguigu.duotai.test;



public class GeometricObject {

    protected String color;

    protected double weigth;

   

    public GeometricObject(String color, double weigth) {

        super();

        this.color = color;

        this.weigth = weigth;

    }

    public String getColor() {

        return color;

    }

    public void setColor(String color) {

        this.color = color;

    }

    public double getWeigth() {

        return weigth;

    }

    public void setWeigth(double weigth) {

        this.weigth = weigth;

    }

   

    public double findArea() {

        return 0.0;

    }

}

2、Circle类(GeometricObject类的第一个子类):

package com.atguigu.duotai.test;



public class Circle extends GeometricObject{  //报错,Circle有一个默认空参的,而GeometricObject没有。

    private double radius;



    public double getRadius() {

        return radius;

    }



    public void setRadius(double radius) {

        this.radius = radius;

    }



    public Circle(String color, double weigth, double radius) {

        super(color, weigth);

        this.radius = radius;

    }

    public double findArea() {

        return Math.PI*radius*radius;

    }

}

3、MyRectangle(GeometricObject类的第二个子类):

package com.atguigu.duotai.test;



public class MyRectangle extends GeometricObject{

    private double width;

    private double height;

    public MyRectangle(String color, double weigth, double width, double height) {

        super(color, weigth);

        this.width = width;

        this.height = height;

    }

    public double getWidth() {

        return width;

    }

    public void setWidth(double width) {

        this.width = width;

    }

    public double getHeight() {

        return height;

    }

    public void setHeight(double height) {

        this.height = height;

    }

   

    public double findArea() {

        return width*height;

    }

}

4、TestGeometric(测试类):

package com.atguigu.duotai.test;



public class TestGeometric {

    public static void main(String[] args) {

        TestGeometric t=new TestGeometric();

       

        Circle c1=new Circle("Green",2.3,1.0);

        Circle c2=new Circle("Red",2.3,1.0);

       

        MyRectangle m1=new MyRectangle("blue",2.3,3.0,2.0);

        t.displayGemoetricObject(c2);

       

        boolean b=t.equalsArea(c1, c2);

        System.out.println(b);

    }

   

    //判断两个对象的面积是否相等

    public boolean equalsArea(GeometricObject o1,GeometricObject o2) {

//      if(o1.findArea()==o2.findArea())

//          return true;

//      else

//          return false;

        return o1.findArea()==o2.findArea();

    }

    public void displayGemoetricObject(GeometricObject o) {

        System.out.println(o.findArea());

    }

}

错误整理:

1、

出现上图所示错误,原因是:SavingAccount类继承父类Account,父类Account类中为书写无参的构造方法。导致此类错误发生。

猜你喜欢

转载自blog.csdn.net/qq_39044046/article/details/93604857