Java面向对象特征之多态

一,多态概述

1.1,什么是多态?

一个对象的多种状态

(老师)(员工)(儿子)

教师 a = 张三

员工 b = 张三

1.2 多态体现

  1,Father类

    1,非静态成员变量x

    2,静态成员变量y

    3,非静态方法eat,方法体输出父类信息

    4,静态方法speak();方法体输出父类信息

  2,Son类

    1,非静态成员变量x

    2,静态成员变量y

    3,非静态方法eat,方法体输出子类信息

    4,静态方法speak();方法体输出子类信息

class Father {
    int x = 1;
    static int y = 2;

    void eat() {
        System.out.println("开吃");
    }

    static void speak() {
        System.out.println("小头爸爸");
    }
}

class Son extends Father {
    int x = 3;
    static int y = 4;

    void eat() {
        System.out.println("大头儿子很能吃");
    }

    static void speak() {
        System.out.println("大头儿子。");
    }
}

class Demo10 {

    public static void main(String[] args) {

        Father f = new Son(); // 父类引用指向了子类对象。
        System.out.println(f.x); // 1
        System.out.println(f.y); // 2

        f.eat(); // 输出的是子类的。
        
        f.speak(); // 输出的是父类
        
    }
}

  3,Son类继承父类

    1,创建Father f = new Son();

      1:这就是父类引用指向了子类对象

      2:问f.x = ?(非静态)

      3:问f.y = ?(静态)

      4:f.eat()输出的是子类还是父类信息?(非静态)

      5:f.speak()输出的是子类还是父类信息?(静态  

  4,总结

    1,当父类和子类具有相同的非静态成员变量,那么多态下访问的是父类成员变量

    2,当父类和子类具有相同的静态成员变量,那么在多态下访问的是父类的静态成员变量

    所以;父类和子类具有相同的成员变量,多态下访问的就是父类的成员变量。

    3,当父类和子类具有相同的非静态方法(就是子类重写父类方法),多态下访问的是子类成员方法

    4,当父类和子类具有相同的静态方法(就是子类重写父类静态方法),多态下访问的就是父类的静态方法。

     所以多态体现为

      1,父类引用变量指向了子类的对象

      2,父类引用也可以接受自己的子类对象。

1.3 多态的前提

类与类之间有关系,继承或者实现

1.4 多态弊端

1,提高扩展性,但是只能使用父类引用指向父类成员。

1.5多特特点

  非静态:

    1,编译时期,参考引用型变量所属的类是否有调用方法,如果有编译通过。没有编译失败

    2,运行时期,参考对象所属类中是否有调用的方法。

    3,总之成员函数在多态调用时,编译看左边,运行看右边

    在多态中,成员变量的特点无论编译和运行参考左边(引用型变量所属的类)

    在多态中,静态成员函数特点,无论编译和运行都参考左边。

 1.6 多态练习

1,多态可以作为形参,接收范围更广的对象,避免函数重载过度使用

例子

  1,定义功能,根据输出任何图形的面积和周长。

    1,定义抽象类abstract MyShape

      1,定义抽象方法 public abstract double getArea();

      2,定义抽象方法 public abstract double getLen();

    2,定义Rect类继承MyShape

      1,定义长和宽成员变量,double width height;

      2,定义无参构造,有参构造

      3,实现父类方法。

    3,定义Cricle 类继承MyShape

      1,定义半径成员变量,和PI常量

      2,无参构造,有参构造

      3,实现父类方法

    4,定义静态方法计算任意图形的面积和周长

      1,未知内容参与运算,不能确定用户出入安何种图形,使用多态。

        1:形参定义为MyShape my

      2,调用计算面积方法,和计算周长方法。并打印

        使用多态特性,子类重写了父类非静态方法,会执行子类的方法。

/*
多态练习
    1:多态可以作为形参,接受范围更广的对象,避免函数重载过度使用。
        1:定义功能,根据输出任何图形的面积和周长。
        子类重写了父类的抽象方法,多态下,会执行子类的非静态方法。
    2:多态可以作为返回值类型。
        获取任意一辆车对象
    3:抽象类和接口都可以作为多态中的父类引用类型。
*/
abstract class MyShape{
    public abstract double getArea();
    public abstract double getLen();
}
class  Rect extends MyShape{
    double width ;
    double height;
    Rect(){
    
    }
    Rect(double width ,double height){
        this.width=width;
        this.height=height;
    }
    public double getArea(){
        return width*height;
    }
    public  double getLen(){
        return 2*(width+height);
    }
    
}
class Circle extends MyShape{
     double r;
     public static final double PI=3.14;
     
     Circle(){
     
     }
     
    Circle(double r){
         this.r=r;
     }
    public double getLen(){
         return 2*PI*r;
     }
    
    public double getArea(){
         return PI*r*r;
     }
}

class Demo11{

    public static void main(String[] args){

        System.out.println();
        
        print(new Rect(3,4)); //MyShape m =new Rect(3,4);
        
        print(new Circle(3));
        
         }
         
         //根据用户传入的图形对象,计算出该图形的面积和周长
         //1:多态可以作为形参,接受范围更广的对象,避免函数重载过度使用。 
         public static void print(MyShape m){  
             System.out.println(m.getLen());
             System.out.println(m.getArea());
         }       
}

 

2,多态可以作为返回值类型。

*
 2:多态可以作为返回值类型。
 获取任意一辆车对象
 1:定义汽车类,有名字和颜色,提供有参和无参构造,有运行的行为。
 2:定义Bmw类,继承Car类,提供无参构造和有参构造(super父类构造),重写父类运行行为。
 3:定义Benz类,继承Car类,提供无参构造和有参构造(super父类构造),重写父类运行行为。
 4:定义Bsj类,继承Car类,提供无参构造和有参构造(super父类构造),重写父类运行行为。
 5:定义静态方法,汽车工厂,随机生产汽车。使用多态定义方法返回值类型。
 1:使用(int)Math.round(Math.random()*2); 生成0-2之间随机数。
 Math 类
 2:使用if else 判断,指定,0,1,2 new 不同汽车 并返回。
 6:调用该方法,发现多态的好处。
 */
class Car {
    String name;
    String color;

    Car() {

    }

    Car(String name, String color) {
        this.name = name;
        this.color = color;
    }

    void run() {
        System.out.println("跑跑。。。。");
    }
}

class Bmw extends Car {
    Bmw() {

    }

    Bmw(String name, String color) {
        super(name, color);
    }

    void run() {
        System.out.println("宝马很拉风。。。。");
    }
}

class Benz extends Car {
    Benz() {

    }

    Benz(String name, String color) {
        super(name, color);
    }

    void run() {
        System.out.println("奔驰商务首选。。。。");
    }
}

class Bsj extends Car {

    Bsj() {

    }

    Bsj(String name, String color) {
        super(name, color);
    }

    void run() {
        System.out.println("泡妞首选。。。。");
    }
}

class Demo12 {

    public static void main(String[] args) {

        int x = 0;
        while (x < 100) {
            Car c = CarFactory();
            c.run();
            x++;
        }

    }

    // 定义静态方法,汽车工厂,随机生产汽车。使用多态定义方法返回值类型。
    // 使用随机数,0.1.2 if 0 bsj 1 bmw 2 bc
    public static Car CarFactory() {
        int x = (int) Math.round(Math.random() * 2);

        if (0 == x) {
            return new Bmw("宝马x6", "红色");
        } else if (1 == x) {
            return new Benz("奔驰", "黑色");
        } else if (2 == x) {
            return new Bsj("保时捷", "棕色");
        } else {
            return new Benz("Smart", "红色");
        }

    }
}

 

3,抽象类和接口都可以作为多态中的父类引用类型。

  例如:sun     Arrays

二, 多态之类型转型

案例1

  1:案例定义Father

    1:定义method1method2方法

  2:定义Son类继承Father

    1:定义method1(重写父类method1)和method2方法

  3:创建Father f=new Son();

    1f.method1() 调用的子类或者父类?

    2f.method2() 编译和运行是否通过?

    3f.method3() 编译和运行是否通过?(编译报错)

 

  4:如何在多态下,使用父类引用调用子类特有方法。

    1:基本类型转换:

      1:自动:小->

      2:强制:大->

    2:类类型转换

      前提:继承,必须有关系

      1:自动:子类转父类

      2:强转:父类转子类

      3:类型转换

        1Son s=(Son)f

        2s.method3();

/*
 如何在多态下,使用父类引用调用子类特有方法。
 1:基本类型转换:
 1:自动:小->大    int x=1 double d=x;
 2:强制:大->小    int y=(int)d;
 2:类类型转换
 前提:继承,必须有关系
 1:自动:子类转父类  Father f=new Son(); 
 2:强转:父类转子类  Son s=(Son)f;    
 1:类型转换
 1:Son s=(Son)f
 2:s.method3(); 
 */
class Father {

    void method1() {
        System.out.println("这是父类1");
    }

    void method2() {
        System.out.println("这是父类2");
    }
}

class Son extends Father {
    void method1() {
        System.out.println("这是子类1");
    }

    void method3() {
        System.out.println("这是子类3");
    }
}

class Demo14 {

    public static void main(String[] args) {
        Father f = new Son();
        f.method1(); // 这是子类1
        f.method2(); // 这是父类2

        // f.method3(); //编译报错。
        // 多态弊端,只能使用父类引用指向父类成员。

        // 类类型转换
        Son s = (Son) f;
        s.method3();

        System.out.println();
    }
}

 

案例2

1:定义Animal类颜色成员变量,无参构造,有参构造,run方法

2:定义Dog类,继承Animal,定义无参构造,有参构造(使用super调用父类有参构造),Dog的特有方法ProtectHome

3:定义Fish类,继承Animal,定义无参构造,有参构造(使用super调用父类有参构造),Fish特有方法swim

4:定义Bird类,继承Animal,定义无参构造,有参构造(使用super调用父类有参构造),Bird特有方法fly

5:使用多态,Animal a=new Dog();

6:调用Dog的特有方法,ProtectHome

  1:类类型转换,Dog d=(Dog)a;

  2d.protectHome

7:非多态

  1Animal a=new Animal();

  2:类类型转换

    Dog d=(Dog)a;  

    d.protectHome();

  3:编译通过,运行出现异常

    1ClassCastException

8:多态例外

  1Animal  a=new Dog();

  2:类类型转换

    1Fish f=(Fish)a;

    2f.fish();

    3:编译通过,运行异常

      1ClassCastException

    4:虽然是多态,但是鸟不能转为狗,狗不能转为鱼,他们之间没有关系。

class Animal {
    String color;

    Animal() {

    }

    Animal(String color) {
        this.color = color;
    }

    void run() {
        System.out.println("跑跑");
    }
}

class Dog extends Animal {
    Dog() {

    }

    Dog(String color) {
        super(color);
    }

    void run() {
        System.out.println("狗儿跑跑");
    }

    void protectHome() {
        System.out.println("旺旺,看家");
    }
}

class Fish extends Animal {
    Fish() {

    }

    Fish(String color) {
        super(color);
    }

    void run() {
        System.out.println("鱼儿水中游");
    }

    void swim() {
        System.out.println("鱼儿游泳");
    }

}

class Demo15 {

    public static void main(String[] args) {

        Animal ani = new Dog();
        // ani.protectHome();
        // 正常转换
        Dog d = (Dog) ani;
        d.protectHome();

        // 多态例外
        Animal an = new Animal();
        // ClassCastException
        // Dog d=(Dog)an

        // 多态例外
        Animal dog = new Dog();
        // ClassCastException
        // Fish f = (Fish) dog;

    }
}

 

案例三

1:定义一功能,接收用户传入动物,根据用于传入的具体动物,执行该动物特有的方法

2:使用多态,方法形参,不能确定用户传入的是那种动物

3:使用instanceof 关键字,判断具体是何种动物,

4:类转换,执行该动物的特有方法。

 

package oop04;

/*
 案例2
 1:定义一功能,接收用户传入动物,根据用于传入的具体动物,执行该动物特有的方法
 2:使用多态,方法形参,不能确定用户传入的是那种动物
 3:使用instanceof 关键字,判断具体是何种动物,
 4:类转换,执行该动物的特有方法。
 */
class Animal {
    String color;

    Animal() {

    }

    Animal(String color) {
        this.color = color;
    }

    void run() {
        System.out.println("跑跑");
    }
}

class Dog extends Animal {
    Dog() {

    }

    Dog(String color) {
        super(color);
    }

    void run() {
        System.out.println("狗儿跑跑");
    }

    void protectHome() {
        System.out.println("旺旺,看家");
    }
}

class Fish extends Animal {
    Fish() {

    }

    Fish(String color) {
        super(color);
    }

    void run() {
        System.out.println("鱼儿水中游");
    }

    void swim() {
        System.out.println("鱼儿游泳");
    }

}

class Bird extends Animal {
    Bird() {

    }

    Bird(String color) {
        super(color);
    }

    void run() {
        System.out.println("鸟儿空中飞");
    }

    void fly() {
        System.out.println("我是一只小小鸟。。。。");
    }
}

class Demo16 {

    public static void main(String[] args) {

        System.out.println();
        doSomething(new Dog());
        doSomething(new Bird());
        doSomething(new Fish());
    }

    // 定义一功能,接收用户传入动物,根据用于传入的具体动物,执行该动物特有的方法
    public static void doSomething(Animal a) {
        if (a instanceof Dog) {
            Dog d = (Dog) a;
            d.protectHome();
        } else if (a instanceof Fish) {
            Fish f = (Fish) a;
            f.swim();
        } else if (a instanceof Bird) {
            Bird b = (Bird) a;
            b.fly();
        } else {
            System.out.println("over");
        }
    }
}

 

 

 

练习:

  1. 多态的体现,前提,好处,弊端?

 

posted @ 2021-08-07 00:11  勇敢面对difficult  阅读(73)  评论(0)    收藏  举报