多态

1       多态

1.1  多态的概述

    1:什么是多态

       一个对象的多种状态

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

       教师 a =老钟;

       员工 b= 老钟;

    2:多态体现

       1:Father类

           1:非静态成员变量x

           2:静态成员变量y

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

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

       2:Son类

           1:非静态成员变量x

           2:静态成员变量y

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

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

class Father {

    intx = 1;

    staticinty = 2;

 

    void eat() {

       System.out.println("开吃");

    }

 

    staticvoid speak() {

       System.out.println("小头爸爸");

    }

}

 

class Son extends Father {

    intx = 3;

    staticinty = 4;

 

    void eat() {

       System.out.println("大头儿子很能吃");

    }

 

    staticvoid speak() {

       System.out.println("大头儿子。");

    }

}

 

class Demo10 {

 

    publicstaticvoid 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:当父类和子类具有相同的静态方法(就是子类重写父类静态方法),多态下访问的是父类的静态方法。

    2:多态体现

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

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

3:多态前提

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

4:多态弊端

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

5:多态特点

    非静态

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

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

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

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

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

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:调用计算面积方法,和计算周长方法。并打印

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

/*

多态练习

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

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

       子类重写了父类的抽象方法,多态下,会执行子类的非静态方法。

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

       获取任意一辆车对象

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

*/

abstractclass MyShape{

    publicabstractdouble getArea();

    publicabstractdouble getLen();

}

class  Rect extends MyShape{

    doublewidth ;

    doubleheight;

    Rect(){

   

    }

    Rect(double width ,double height){

       this.width=width;

       this.height=height;

    }

    publicdouble getArea(){

       returnwidth*height;

    }

    public  double getLen(){

       return 2*(width+height);

    }

   

}

class Circle extends MyShape{

     doubler;

     publicstaticfinaldoublePI=3.14;

     

     Circle(){

     

     }

     

    Circle(double r){

        this.r=r;

     }

    publicdouble getLen(){

        return 2*PI*r;

     }

   

    publicdouble getArea(){

        returnPI*r*r;

     }

}

 

class Demo11{

 

    publicstaticvoid main(String[] args){

 

       System.out.println();

      

       print(new Rect(3,4)); //MyShape m =new Rect(3,4);

      

       print(new Circle(3));

      

        }

       

        //根据用户传入的图形对象,计算出该图形的面积和周长

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

        publicstaticvoid print(MyShape m){ 

           System.out.println(m.getLen());

           System.out.println(m.getArea());

        }      

}

 

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

       获取任意一辆车对象

           1:定义汽车类,有名字和颜色,提供有参和无参构造,有运行的行为。

2:定义Bmw类,继承Car类,提供无参构造和有参构造(super父类构造),重写父类运行行为。

3:定义Benz类,继承Car类,提供无参构造和有参构造(super父类构造),重写父类运行行为。

4:定义Bsj类,继承Car类,提供无参构造和有参构造(super父类构造),重写父类运行行为。

           5:定义静态方法,汽车工厂,随机生产汽车。使用多态定义方法返回值类型。

              1:使用(int)Math.round(Math.random()*2); 生成0-2之间随机数。

              2:使用if else 判断,指定,0,1,2 new 不同汽车并返回。

           6:调用该方法,发现多态的好处。

*

 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 {

 

    publicstaticvoid 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

    publicstatic Car CarFactory() {

       int x = (int) Math.round(Math.random() * 2);

 

       if (0 == x) {

           returnnew Bmw("宝马x6", "红色");

       } elseif (1 == x) {

           returnnew Benz("奔驰", "黑色");

       } elseif (2 == x) {

           returnnew Bsj("保时捷", "棕色");

       } else {

           returnnew Benz("Smart", "红色");

       }

 

    }

}

 

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

           1:sun Arrays

6:多态之类型转型

    1:案例定义Father类

       1:定义method1和method2方法

    2:定义Son类继承Father类

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

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

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

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

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

 

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

       1:基本类型转换:

           1:自动:小->大

           2:强制:大->小

       2:类类型转换

           前提:继承,必须有关系

           1:自动:子类转父类

           2:强转:父类转子类

           3:类型转换

              1:Son s=(Son)f

              2:s.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:类型转换

 1Son s=(Son)f

 2s.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 {

 

    publicstaticvoid main(String[] args) {

       Father f = new Son();

       f.method1(); // 这是子类1

       f.method2(); // 这是父类2

 

       // f.method3(); //编译报错。

       // 多态弊端,只能使用父类引用指向父类成员。

 

       // 类类型转换

       Son s = (Son) f;

       s.method3();

 

       System.out.println();

    }

}

 

5:案例:

    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;

       2:d.protectHome

    7:非多态

       1:Animal a=new Animal();

       2:类类型转换

           Dog d=(Dog)a; 

           d.protectHome();

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

           1:ClassCastException

    8:多态例外

           1:Animal  a=new Dog();

           2:类类型转换

              1:Fish f=(Fish)a;

              2:f.fish();

              3:编译通过,运行异常

                  1:ClassCastException

              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 {

 

    publicstaticvoid 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;

 

    }

}

 

6:案例2

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 {

 

    publicstaticvoid main(String[] args) {

 

       System.out.println();

       doSomething(new Dog());

       doSomething(new Bird());

       doSomething(new Fish());

    }

 

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

    publicstaticvoid doSomething(Animal a) {

       if (a instanceof Dog) {

           Dog d = (Dog) a;

           d.protectHome();

       } elseif (a instanceof Fish) {

           Fish f = (Fish) a;

           f.swim();

       } elseif (a instanceof Bird) {

           Bird b = (Bird) a;

           b.fly();

       } else {

           System.out.println("over");

       }

    }

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值