2020年8月13日 多态 及应用:多态数组、多态参数

  

/*
 * 一、面向对象的基本特征:
 * 1、封装
 *     和权限修饰符有关    
 * 2、继承
 *     extends
 * 3、多态
 *     
 * 二、多态
 * 多态:多种形态
 * 
 * 变量的引用形式:
 * (1)本态引用:左边的变量与右边的对象是同一种类型
 * (2)多态引用:左边的变量是父类类型,右边的对象是子类的对象
 * 
 * 多态的表现出来的特征:编译类型与运行时类型不一致
 *     编译的时候,按照父类的类型进行编译的
 *     执行的方法,按照子类进行运行,是“执行子类重写的方法”
 *     
 *     编译看左边,运行看右边
 * 
 * 前提:(1)继承(2)重写(3)多态引用
 * 用途:方法的动态绑定
 * 强调:多态和属性无关,只说方法
 * 
 * 网上也有人这么说,把重载也归为多态,我们不这么认为
 * 
 */
package com.atguigu.test02.polymorphism;

public class TestPolymorphism {
    public static void main(String[] args) {
        //1、本态引用
//        Person p = new Person();
//        Woman w = new Woman();
//        Man m = new Man();
        
        //2、多态引用
        Person p2 = new Woman();
        Person p3 = new Man();
        
        p2.eat();
        p2.walk();
//        p2.shop();
        
        System.out.println(p2.info);//属性没有多态,只看编译时类型
    }
}
class Person{
    String info = "atguigu";
    public void eat(){
        System.out.println("吃饭");
    }
    public void walk(){
        System.out.println("走路");
    }
}
class Woman extends Person{
    String info = "尚硅谷";
    public void eat(){
        System.out.println("细嚼慢咽的吃饭");
    }
    public void walk(){
        System.out.println("婀娜多姿走路");
    }
    public void shop(){
        System.out.println("买买买...");
    }
}
class Man extends Person{
    public void eat(){
        System.out.println("狼吞虎咽的吃饭");
    }
    public void walk(){
        System.out.println("大摇大摆的走路");
    }
    public void smoke(){
        System.out.println("吞云吐雾");
    }
}

/*
* 多态的好处:
* 使得程序员编写代码更灵活
* 多态的应用:
* (1)多态数组:
* 数组的元素是父类的类型,实际存储的是子类的对象
* 用这样的数组,就可以统一管理,所有子类的对象
*/

package com.atguigu.test02.polymorphism;


public class TestUse1 {
    public static void main(String[] args) {
        /*
         * 创建一个数组,可以存储各种图形的对象,包括圆对象,矩形对象,三角形对象...
         */
        //本态数组
        //Circle[] yuans = new Circle[3];//这个数组存圆
        //Rectangle[] jus = new Rectangle[3];//这个数组存矩形
        
        Graphic[] all = new Graphic[3];//这个数组就可以存储各种图形的对象
        //左边的元素arr[0]是Graphic类型,右边是子类圆对象
        all[0] = new Circle(1.2);
        
        //左边的g2是Graphic,右边的是矩形对象
        Graphic g2 = new Rectangle(2, 4);
        all[1] = g2;
        
        all[2] = new Circle(4.2);
        
        //遍历所有图形的面积
        for (int i = 0; i < all.length; i++) {
            //执行哪个getArea()方法,要看all[i]中存储的是哪个子类的对象
            System.out.println("面积:" + all[i].getArea());
        }
    }
}
//Graphic图形
class Graphic{
    public double getArea(){
        return 0.0;//这句话没有什么意义,只是为了保证语法
    }
}
class Circle extends Graphic{
    private double radius;

    public Circle(double radius) {
        this.radius = radius;
    }
    //重写
    public double getArea(){
        return 3.14 * radius * radius;
    }
}
class Rectangle extends Graphic{
    private double length;
    private double width;
    public Rectangle(double length, double width) {
        this.length = length;
        this.width = width;
    }
    //重写
    public double getArea(){
        return length * width;
    }
}

/*
* 多态的应用:
* (2)多态参数:
* 形参是父类的类型,实参是子类的对象
*/

package com.atguigu.test02.polymorphism;


public class TestUse2 {
    //这个方法,能够检查所有的动物吃东西是否正常
    //没有多态的话,需要重载很多个
    /*public static void check(Dog dog ){
        dog.eat();
    }
    public static void check(Cat cat ){
        cat.eat();
    }*/
    
    public static void check(Animal a){
        a.eat();
    }
    
    public static void main(String[] args) {
        //匿名对象
        check(new Dog());//隐含了,形参Animal a = 实参  new Dog()
        check(new Cat());//隐含了,形参Animal a = 实参  new Cat()
        
        Dog d = new Dog();
        check(d);//有名对象
    }
}
class Animal{
    public void eat(){
        System.out.println("吃东西");
    }
}
class Dog extends Animal{
    public void eat(){
        System.out.println("啃骨头");
    }
}
class Cat extends Animal{
    public void eat(){
        System.out.println("吃鱼");
    }
}

 多态练习:

package com.atguigu.test;
/*

 * 2、练习题2
   (1)声明一个Person类,有一个方法
   public void toilet(){
   }
   (2)声明一个子类Woman类,重写方法
   (3)声明一个子类Man类,重写方法
   (4)在测试类中声明一个方法,
   public static void goToToilet(Person p){
   //调用toilet()
   }

 */
public class TesteExer2 {
    public static void main(String[] args) {
        Woman m1 = new Woman();
        goToToilet(m1);
        goToToilet(new Man());
    }
    public static void goToToilet(Person p) {
        p.toilet();
    }
}
class Person{
    public void toilet(){
        System.out.println("上厕所");
    }
}
class Woman extends Person{
    public void toilet(){
        System.out.println("上女厕所");
    }
}
class Man extends Person{
    public void toilet(){
        System.out.println("上男厕所");
    }
}
package com.atguigu.test;
/*
1、练习题
(1)声明Traffic,
public void drive()方法
(2)声明子类Car,Bicycle,甚至可以声明Car的各种子类,例如BMW,Benz类等
(3)在测试类的main中创建一个数组,有各种交通工具,遍历调用drive()方法
 */
public class TestExer1 {
    public static void main(String[] args) {
        Traffic[] all = new Traffic[5];
        
        all[0] = new Car();
        all[1] = new Bicycle();
        all[2] = new Car();
        all[3] = new Bicycle();
        all[4] = new Car();
        
        for (int i = 0; i < all.length; i++) {
            all[i].drive();
        }
        
        
    }

}
class Traffic{
    public void drive(){
        System.out.println("驾驶");
    }
}

class Car extends Traffic{
    public void drive(){
        System.out.println("开车");
    }
}
class Bicycle extends Traffic{
    public void drive(){
        System.out.println("骑自行车");
    }    
}
原文地址:https://www.cnblogs.com/douyunpeng/p/13496388.html