精华内容
下载资源
问答
  • 多态常见应用场景举例

    千次阅读 2020-06-12 12:59:36
    /**多态在实际开发中的使用,以下为主人喂养宠物的例子说明多态的作用 *1.主人喂养宠物这个场景需要进行类型的抽象: *---主人【类】 宠物【类】 *--主人可以喂养宠物 所以主人有喂养这个动作 *-- 宠物【类】 ...

    package day0611;

    public class Test {

        /**多态在实际开发中的使用,以下为主人喂养宠物的例子说明多态的作用
         *1.主人喂养宠物这个场景需要进行类型的抽象:
         *---主人【类】 宠物【类】
         *--主人可以喂养宠物 所以主人有喂养这个动作
         *-- 宠物【类】
         *--宠物可以吃东西,所以宠物有吃东西这个动作
         *
         *--2.面向对象编程的核心:定义好类,将类实例化为对象,给一个环境驱使一下,让各个对象之间协作起来形成一个系统
         *3.多态的作用是什么
         */
        public static void main(String[] args) {//有多态后,测试类中没什么大的变化,还是要把具体的事物猫 狗类创建。

            //创建主人对象
            Master ZhangSan=new Master();

            Cat cat=new Cat();//类是无法进行协作的,需要把类实例为对象,对象在java中才可以进行协作。
            ZhangSan.feed(cat);//ZhangSan和cat都是创建的对象,通过对象吧事物联系了起来。
            Dog dog=new Dog();
            ZhangSan.feed(dog);//在这个传参的过程中,相当于发生了:Pet pet=new Dog();这就是向上转型,或者说是父类的引用指向了子类的对象,这就呼应的多态的定义:Pet pet=new Dog();
    //那么,综合起来,有继承 有方法的重写,有向上转型。者就完成了多态。
        }

    }

     

    package day0611;

    /**
     * 主人

    */
    public class Master {
        /**
         * 这种方式没有使用多态,存在的缺点是:master的扩展能力差,因为要增加一个新的宠物,Master类就要增加一个新的方法
         * 喂养宠物的方法:增加了喂狗的方法后,这个就要改了,不合理
        */
    /*public void feed(Cat c){
        c.eat();//这里并没有创建对象,也没有静态类,之所以可以直接调用是因为传参后,相当于传了对象,引用,可以直接调用,记住就可以了

    }

    public void feed(Dog d){
        d.eat();

    }*/
    //Master和Cat Dog这两个类型的关联类型很强,耦合度很高,扩展能力差


    //降低程序的耦合度【解耦合】,提高程序的扩展力,【软件开发的一个重要的目标】
    public void feed(Pet pet){//参数是pet,两类建立了联系
        pet.eat();
    }
    }

    package day0611;
    /**
     * 宠物类
     *
     * @author Administrator
     *
     */
    public class Pet {

        public void eat(){
            /**
             *所有的宠物都可以吃东西
             */
        }
    }
     

    package day0611;
    /**
     * 宠物小猫
    */
    public class Cat extends Pet{
    //小猫爱吃鱼

    public void eat(){

    System.out.println("小猫正在吃鱼");
    }
    }
     

    package day0611;
    /**
     * 宠物小狗
     */
    public class Dog extends Pet{
    //宠物小狗喜欢吃骨头
        public void eat(){
            System.out.println("小狗正在吃骨头");
        }
    }
     

    总结:多态的核心是在哪个类里可以体现多态,这个类的方法如果不使用多态,就需要写多个方法。那个类里使用多态的语句,比如是饲养员Person这个类。比如饲养方法,饲养的是狗 猫 需要不同的方法。重要的就是测试类和主人类,测试类中创建对象,主人类中定义声明核心方法feed()。

    另有概述参考本人另一篇java多态。

    展开全文
  • 一 : 多态 1.1 什么是多态 多态: 把子类对象伪装成父类类型 让父类类型指向子类对象 给子类对象起一个父类类型的名字 父类类型的引用=子类类型的对象 1.2 多态对象有那些特点 多态对象: 起了父类类型名字的子类...

    一 : 多态

    1.1 什么是多态

    多态: 把子类对象伪装成父类类型

    • 让父类类型指向子类对象
    • 给子类对象起一个父类类型的名字
    • 父类类型的引用=子类类型的对象

    1.2 多态对象有那些特点

    多态对象: 起了父类类型名字的子类对象

    • 特点1:多态对象不能访问子类特有成员
    • 特点2:多态对象被重新定义的属性表现的是父类中的数据
    • 特点3:多态对象被重写的方法表现的是子类中定义的方法
    • 总而言之:多态对象除了重写的方法 其他和父类对象完全相同

    1.3 什么时候使用多态

    情况1

    cat类 dog类

    • 饲养员类: wei方法:给狗、猫喂食物、运动起来来
    • 不使用多态
    public static void main(String[] args) {
    		Dog1 d1=new Dog1("哈趴狗");
    		Cat1 c1=new Cat1("波斯猫");
    		Demo02DuoTaiUse1  syy=new Demo02DuoTaiUse1();
    		syy.wei(c1);
            syy.wei(d1);
        }
    	//方法可以使用的数据:成员变量+参数列表
    	private void wei(Dog1 d) {//此方法只能实现喂狗
    		d.eat();
    		d.yunDong();
    	}
    	private void wei(Cat1 d) {//此方法只能实现喂猫
    		d.eat();
    		d.yunDong();
    	}
    }
    class Dog1{
    	String name;
    	public Dog1(String name) {
    		this.name=name;
    	}
    	void eat() {
    		System.out.println("狗:"+name+"正在吃骨头!");
    	}
    	void yunDong() {
    		System.out.println("狗"+name+"看门!");
    	}
    }
    class Cat1{
    	String name;
    	public Cat1(String name) {
    		this.name=name;
    	}
    	void eat() {
    		System.out.println("猫:"+name+"正在吃鱼!");
    	}
    	void yunDong() {
    		System.out.println("猫"+name+"晒太阳!");
    	}
    
    • 不使用多态实现:

      • 1 代码复用性差:需要为每种动物写一个wei方法
      • 2 代码扩展性差:如果有新的动物类型 需要修改饲养员类 添加新的wei方法
      • 3 代码耦合度高:饲养员类中直接使用dog类
    • 使用多态

    public static void main(String[] args) {
    		//5 调用方法时   传递任意子类类型的对象
    		Cat2 c=new Cat2("波斯猫");
    		wei(c);
    		Dog2 d=new Dog2("哈趴狗");
    		wei(d);
        }
    	//4 定义方法时 不要把形参定义为具体的子类类型  定义为父类类型
    	public static void wei(Animal2 d) {//此方法只能实现喂狗
    		d.eat();
    		d.yunDong();
    	}
    
    }
    //1创建父类: 抽取子类中共同的数据和功能写成父类
    abstract class Animal2{
    	String name;
    	abstract void eat();//eat方法方法体无法实现:信息不完整
    	abstract void yunDong();
    }
    //2让所有子类继承父类
    class Dog2 extends Animal2{
    	public Dog2 (String name) {
    		this.name=name;
    	}
    	//3根据子类的需求 实现父类的抽象方法
    	void eat() {
    		System.out.println("狗:"+name+"正在吃骨头!");
    	}
    	void yunDong() {
    		System.out.println("狗"+name+"看门!");
    }
    }
    class Cat2 extends Animal2{
    	public Cat2(String name) {
    		this.name=name;
    	}
    	void eat() {
    		System.out.println("猫:"+name+"正在吃鱼!");
    	}
    	void yunDong() {
    		System.out.println("猫"+name+"晒太阳!");
    	}
    

    多态使用场景1:定义方法参数列表时 定义为父类类型 这样就可以传递任意子类类型的对象

    情况2

    设计一个台灯类Lamp
    其中台灯有开灯(on)这个方法,
    设计俩个灯泡类
    其中有红灯泡(RedBulb) 和绿灯泡(GreenBulb)
    他们都有一个发亮的方法,请设计出一段代码可以使台灯开启灯泡发亮

    • 不使用多态
    public class LianXi1_1 {
    //不使用多态
    	public static void main(String[] args) {
    		//创建灯泡对象
    		RedBulb1 r1=new RedBulb1();
    		GreenBulb1 g1=new GreenBulb1();
    		//创建台灯对象
    		Lamp1 l1=new Lamp1();
    		//给台灯对象的属性赋值
    		l1.r=r1;
    		l1.g=g1;
            //调用台灯对象的方法
    		l1.on();
           }
    }
    class Lamp1{//台灯类
    	//灯泡是台灯的一个数据
    	RedBulb1 r;//定义成员变量记录需要安装的红灯泡
    	GreenBulb1 g;//定义成员变量记录需要安装的绿灯泡
    	void on() {
    		if (r!=null) {r.light();}
    		if (g!=null) {g.light();}
    		
    	}
    }
    class RedBulb1{
    	void light(){
    		System.out.println("红灯泡  发光:红");
    	}
    }
    class GreenBulb1{
    	void light(){
    		System.out.println("绿灯泡  发光:绿");
    	}
    }
    
    • 缺点

      • 1:代码复用性差:有几种灯泡类型 在台灯类中就需要定义几个属性 而且在on方法中进行多次if判断
      • 2:扩展性差:有新灯泡类型 需要更改Lamp类 添加新属性 修改on方法
      • 3:耦合性强
    • 使用多态

    public class LianXi1_2 {
    //使用多态
    	public static void main(String[] args) {
    	    //创建灯泡对象
    		RedBulb r1=new RedBulb();
    		GreenBulb g1=new GreenBulb();
    		//创建台灯对象
    		Lamp l1=new Lamp();
    		//给台灯对象的属性赋值
    		l1.b=r1;
    		l1.b=g1;
    		//调用台灯对象的方法
    		l1.on();
    	}
        class Lamp{//台灯类
    	//灯泡是台灯的一个数据
    	//定义父类类型的成员变量
    	Buib2 b;
    	void on() {
    		if (b!=null) {b.light();}
    	}
    }
    //抽取子类中共同数据和功能形成父类
    abstract class Buib2{
    	abstract void light();
    }
    //让所有子类继承父类
    class RedBulb extends Buib2{
    	//根据子类需求  实现父类方法
    	void light() {
    		System.out.println("红灯泡  发光:红");
    	}
    }
    class GreenBulb extends Buib2{
    	void light() {
    		System.out.println("绿灯泡  发光:绿");
    	}
    }
    

    多态使用场景2:定义成员变量时 定义为父类类型 这样就可以赋值任意子类类型的对象

    情况3

    三种类型:circle square rect三种类型 都有各自的属性 都有打印周长和打印面积的方法
    写一个方法 传递一个int参数n n>1 返回一个长方形对象 n<1 返回一个正方形对象
    n=1 返回一个圆形对象

    • 只能通过多态实现
    public class LianXi1_3 {
    	
    	public static void main(String[] args) {
              Shape s=get(1);//多态
              s.printZC();
              s.printMJ();
    	   }
        	//4 定义返回值类型时   定义为父类类型
    	public static Shape get(int n) {
    		if (n>1) {return new Rect(3, 2);}
    		if (n<1) {return new Squarel(1);}
    		return new Circle(1);
    	}
        abstract class Shape{
    	public abstract void printZC();
    	public abstract void printMJ();
    }
    //2 所有子类继承父类
    class Circle extends Shape{
    	double r;
    	final double PI=3.14;
    	public Circle(double r) {this.r=r;}
    	//3 子类根据自己的需求  实现父类的方法
    	public void printZC() {System.out.println("圆 周长:"+2*PI*r);}
    	public void printMJ() {System.out.println("圆 面积:"+r*PI*r);}
    }
    class Squarel extends Shape {
    	double bianChang;
    	public Squarel (double bianChang) {this.bianChang=bianChang;}
    	public void printZC() {System.out.println("正方形  周长:"+bianChang*4);}
    	public void printMJ() {System.out.println("正方形 面积:"+bianChang*bianChang);}
    }
    class Rect extends Shape{
    	double chang,kuan;
    	public Rect (double chang,double kuan) {this.chang=chang;this.kuan=kuan;}
    	public void printZC() {System.out.println("长方形  周长:"+2*(chang+kuan));}
    	public void printMJ() {System.out.println("长方形:"+chang *kuan);}
    }
    

    多态使用场景3:定义方法返回值类型时 定义为父类类型 这样就可以返回任意子类类型的对象

    情况4

    创建一个数组 :装2个圆、2个长方形、2个正方形

    • 只能通过多态实现
    public static void createArray() {
    		Circle c1=new Circle(1);
    		Squarel s1=new Squarel(2);
    		Rect r1=new Rect(2, 1);
    		Circle c2=new Circle(11);
    		Squarel s2=new Squarel(21);
    		Rect r2=new Rect(21, 11);
    		//定义数组必须明确:元素类型+元素个数
    		Shape[] arr=new Shape[] {c1,c2,s1,s2,r1,r2};//多态
    	}
    

    多态使用场景4:定义数组元素类型时 定义为父类类型 这样就可以装任意子类类型的对象

    总结: 定义方法参数列表时、定义方法返回值类型时、定义类的成员变量时、定义数组元素类型时,都定义为父类类型,这样就可以传递、返回、赋值、装任意子类类型的对象定义时定义父类类型 使用时使用子类类型的对象

    展开全文
  • 多态示例代码

    2014-08-21 23:28:55
    应用场合,类型转换,instanceof运算符,使用父类作为方法形参实现多态,使用父类作为返回值实现多态
  • 文章目录接口接口的作用接口的语法实现接口实现多个接口的语法接口的扩展类型转换类型转换的概念类型转换规则隐式类型转换显式类型转换类型转换的主要应用场合类型转换的主要应用场合多态多态的概念多态的目的 ...
  • 展开全部面向对象编程有三大特性:636f70793231313335323631343130323136353331333361313861封装、继承、多态。封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据。对外界...

    展开全部

    面向对象编程有三大特性:636f70793231313335323631343130323136353331333361313861封装、继承、多态。

    封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据。对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法。

    继承是为了重用父类代码。两个类若存在IS-A的关系就可以使用继承。,同时继承也为实现多态做了铺垫。

    那么什么是多态呢?多态的实现机制又是什么?请看我一一为你揭开:

    所谓多态

    就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。

    比如你是一个酒神,对酒情有独钟。某日回家发现桌上有几个杯子里面都装了白酒,从外面看我们是不可能知道这是些什么酒,只有喝了之后才能够猜出来是何种酒。你一喝,这是剑南春、再喝这是五粮液、再喝这是酒鬼酒….在这里我们可以描述成如下:

    酒 a = 剑南春

    酒 b = 五粮液

    酒 c = 酒鬼酒

    这里所表现的的就是多态。剑南春、五粮液、酒鬼酒都是酒的子类,我们只是通过酒这一个父类就能够引用不同的子类,这就是多态——我们只有在运行的时候才会知道引用变量所指向的具体实例对象。

    诚然,要理解多态我们就必须要明白什么是“向上转型”。在继承中我们简单介绍了向上转型,这里就在啰嗦下:在上面的喝酒例子中,酒(Win)是父类,剑南春(JNC)、五粮液(WLY)、酒鬼酒(JGJ)是子类。我们定义如下代码:

    JNC a = new JNC();

    对于这个代码我们非常容易理解无非就是实例化了一个剑南春的对象嘛!但是这样呢?

    Wine a = new JNC();

    在这里我们这样理解,这里定义了一个Wine 类型的a,它指向JNC对象实例。由于JNC是继承与Wine,所以JNC可以自动向上转型为Wine,所以a是可以指向JNC实例对象的。这样做存在一个非常大的好处,在继承中我们知道子类是父类的扩展,它可以提供比父类更加强大的功能,如果我们定义了一个指向子类的父类引用类型,那么它除了能够引用父类的共性外,还可以使用子类强大的功能。

    但是向上转型存在一些缺憾,那就是它必定会导致一些方法和属性的丢失,而导致我们不能够获取它们。所以父类类型的引用可以调用父类中定义的所有属性和方法,对于只存在与子类中的方法和属性它就望尘莫及了。

    public class Wine {

    public void fun1(){

    System.out.println("Wine 的Fun.....");

    fun2();

    }

    public void fun2(){

    System.out.println("Wine 的Fun2...");

    }

    }

    public class JNC extends Wine{

    /**

    * @desc 子类重载父类方法

    *        父类中不存在该方法,向上转型后,父类是不能引用该方法的

    * @param a

    * @return void

    */

    public void fun1(String a){

    System.out.println("JNC 的 Fun1...");

    fun2();

    }

    /**

    * 子类重写父类方法

    * 指向子类的父类引用调用fun2时,必定是调用该方法

    */

    public void fun2(){

    System.out.println("JNC 的Fun2...");

    }

    }

    public class Test {

    public static void main(String[] args) {

    Wine a = new JNC();

    a.fun1();

    }

    }

    -------------------------------------------------

    Output:

    Wine 的Fun.....

    JNC 的Fun2...

    从程序的运行结果中我们发现,a.fun1()首先是运行父类Wine中的fun1().然后再运行子类JNC中的fun2()。

    分析:在这个程序中子类JNC重载了父类Wine的方法fun1(),重写fun2(),而且重载后的fun1(String a)与 fun1()不是同一个方法,由于父类中没有该方法,向上转型后会丢失该方法,所以执行JNC的Wine类型引用是不能引用fun1(String a)方法。而子类JNC重写了fun2() ,那么指向JNC的Wine引用会调用JNC中fun2()方法。

    所以对于多态我们可以总结如下:

    指向子类的父类引用由于向上转型了,它只能访问父类中拥有的方法和属性,而对于子类中存在而父类中不存在的方法,该引用是不能使用的,尽管是重载该方法。若子类重写了父类中的某些方法,在调用该些方法的时候,必定是使用子类中定义的这些方法(动态连接、动态调用)。

    对于面向对象而已,多态分为编译时多态和运行时多态。其中编辑时多态是静态的,主要是指方法的重载,它是根据参数列表的不同来区分不同的函数,通过编辑之后会变成两个不同的函数,在运行时谈不上多态。而运行时多态是动态的,它是通过动态绑定来实现的,也就是我们所说的多态性。

    多态的实现

    2.1实现条件

    在刚刚开始就提到了继承在为多态的实现做了准备。子类Child继承父类Father,我们可以编写一个指向子类的父类类型引用,该引用既可以处理父类Father对象,也可以处理子类Child对象,当相同的消息发送给子类或者父类对象时,该对象就会根据自己所属的引用而执行不同的行为,这就是多态。即多态性就是相同的消息使得不同的类做出不同的响应。

    Java实现多态有三个必要条件:继承、重写、向上转型。

    继承:在多态中必须存在有继承关系的子类和父类。

    重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。

    向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法。

    只有满足了上述三个条件,我们才能够在同一个继承结构中使用统一的逻辑实现代码处理不同的对象,从而达到执行不同的行为。

    对于Java而言,它多态的实现机制遵循一个原则:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。

    2.2实现形式

    在Java中有两种形式可以实现多态。继承和接口。

    2.2.1、基于继承实现的多态

    基于继承的实现机制主要表现在父类和继承该父类的一个或多个子类对某些方法的重写,多个子类对同一方法的重写可以表现出不同的行为。

    public class Wine {

    private String name;

    public String getName() {

    return name;

    }

    public void setName(String name) {

    this.name = name;

    }

    public Wine(){

    }

    public String drink(){

    return "喝的是 " + getName();

    }

    /**

    * 重写toString()

    */

    public String toString(){

    return null;

    }

    }

    public class JNC extends Wine{

    public JNC(){

    setName("JNC");

    }

    /**

    * 重写父类方法,实现多态

    */

    public String drink(){

    return "喝的是 " + getName();

    }

    /**

    * 重写toString()

    */

    public String toString(){

    return "Wine : " + getName();

    }

    }

    public class JGJ extends Wine{

    public JGJ(){

    setName("JGJ");

    }

    /**

    * 重写父类方法,实现多态

    */

    public String drink(){

    return "喝的是 " + getName();

    }

    /**

    * 重写toString()

    */

    public String toString(){

    return "Wine : " + getName();

    }

    }

    public class Test {

    public static void main(String[] args) {

    //定义父类数组

    Wine[] wines = new Wine[2];

    //定义两个子类

    JNC jnc = new JNC();

    JGJ jgj = new JGJ();

    //父类引用子类对象

    wines[0] = jnc;

    wines[1] = jgj;

    for(int i = 0 ; i 

    System.out.println(wines[i].toString() + "--" + wines[i].drink());

    }

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

    }

    }

    OUTPUT:

    Wine : JNC--喝的是 JNC

    Wine : JGJ--喝的是 JGJ

    在上面的代码中JNC、JGJ继承Wine,并且重写了drink()、toString()方法,程序运行结果是调用子类中方法,输出JNC、JGJ的名称,这就是多态的表现。不同的对象可以执行相同的行为,但是他们都需要通过自己的实现方式来执行,这就要得益于向上转型了。

    我们都知道所有的类都继承自超类Object,toString()方法也是Object中方法,当我们这样写时:

    Object o = new JGJ();

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

    输出的结果是Wine : JGJ。

    Object、Wine、JGJ三者继承链关系是:JGJ—>Wine—>Object。所以我们可以这样说:当子类重写父类的方法被调用时,只有对象继承链中的最末端的方法才会被调用。但是注意如果这样写:

    Object o = new Wine();

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

    输出的结果应该是Null,因为JGJ并不存在于该对象继承链中。

    所以基于继承实现的多态可以总结如下:对于引用子类的父类类型,在处理该引用时,它适用于继承该父类的所有子类,子类对象的不同,对方法的实现也就不同,执行相同动作产生的行为也就不同。

    如果父类是抽象类,那么子类必须要实现父类中所有的抽象方法,这样该父类所有的子类一定存在统一的对外接口,但其内部的具体实现可以各异。这样我们就可以使用顶层类提供的统一接口来处理该层次的方法。

    2.2.2、基于接口实现的多态

    继承是通过重写父类的同一方法的几个不同子类来体现的,那么就可就是通过实现接口并覆盖接口中同一方法的几不同的类体现的。

    在接口的多态中,指向接口的引用必须是指定这实现了该接口的一个类的实例程序,在运行时,根据对象引用的实际类型来执行对应的方法。

    继承都是单继承,只能为一组相关的类提供一致的服务接口。但是接口可以是多继承多实现,它能够利用一组相关或者不相关的接口进行组合与扩充,能够对外提供一致的服务接口。所以它相对于继承来说有更好的灵活性。

    展开全文
  • 多态价值很大,使用场景很多,几乎所有的系统或软件,都能看到它的应用。这篇文章尽可能通过一个精简的例子说明它的价值和使用方法。如果不用多态,方法怎么写;使用多态,又是怎么写。 为了一脉相承,做到一致性,...

    多态真的有用吗?今天番茄加速就来说一说。在这里插入图片描述

    如果说OOP的封装和继承使用起来更加直观易用,那么作为第三大特性的多态,在实践中真正运用起来就不那么容易。有的读者OOP编程初期,可能对多态的价值体会不深刻,甚至都已经淡忘它的存在。

    那么问题就在:多态到底真的有用吗?到底使用在哪些场景?

    多态价值很大,使用场景很多,几乎所有的系统或软件,都能看到它的应用。这篇文章尽可能通过一个精简的例子说明它的价值和使用方法。如果不用多态,方法怎么写;使用多态,又是怎么写。

    为了一脉相承,做到一致性,仍然基于上面的案例,已经创建好的Cat类要有一个方法打印和返回它的爬行速度。同时需要再创建一个类Bird,要有一个方法打印和返回它的飞行速度;

    如果不使用多态,为Cat类新增一个方法:

    class Cat(Animal):

    def init(self,name,speed,color,genre):

    super().init(name,speed)

    self.color = color

    self.genre = genre

    # 添加方法

    def getRunningSpeed(self):

    print(‘running speed of %s is %s’ %(self.name, self._speed))

    return self._speed

    重新创建一个Bird类:

    class Bird(Animal):

    def init(self,name,speed,color,genre):

    super().init(name,speed)

    self.color = color

    self.genre = genre

    # 添加方法

    def getFlyingSpeed(self):

    print(‘flying speed of %s is %s’ %(self.name, self._speed))

    return self._speed

    最后,上面创建的Manager类会引用Cat和Bird类,但是需要修改recordTime方法,因为Cat它是爬行的,Bird它是飞行的,所以要根据对象类型的不同做逻辑区分,如下所示:

    # 模块名称:manager.py

    import time

    from animal import (Animal,Cat,Bird)

    class Manager():

    def init(self,animal):

    self.animal = animal

    def recordTime(self):

    self.__t = time.time()

    if isinstance(self.animal, Cat):

    print(‘feeding time for %s is %.0f’%(self.animal.name,self.__t))

    self.animal.getRunningSpeed()

    if isinstance(self.animal,Bird):

    print(‘feeding time for %s is %.0f’%(self.animal.name,self.__t))

    self.animal.getFlyingSpeed()

    def getFeedingTime(self):

    return ‘%0.f’%(self.__t,)

    如果再来一个类,我们又得需要修改recordTime,再增加一个if分支,从软件设计角度讲,这种不断破坏封装的行为不可取。

    但是,使用多态,就可以保证recordTime不被修改,不必写很多if分支。怎么来实现呢?

    首先,在基类Animal中创建一个基类方法,然后Cat和Bird分别重写此方法,最后传入到Manager类的animal参数是什么类型,在recordTime方法中就会对应调用这个animal实例的方法,这就是多态。

    代码如下:

    animal2.py 模块如下:

    # animal2.py 模块

    class Animal():

    cprop = “我是类上的属性cprop”

    def init(self,name,speed):

    self.name = name # 动物名字

    self._speed = speed # 动物行走或飞行速度

    def str(self):

    return ‘’'Animal({0.name},{0._speed}) is printed

    name={0.name}

    speed={0._speed}’’’.format(self)

    def getSpeedBehavior(self):

    pass

    class Cat(Animal):

    def init(self,name,speed,color,genre):

    super().init(name,speed)

    self.color = color

    self.genre = genre

    # 重写方法

    def getSpeedBehavior(self):

    print(‘running speed of %s is %s’ %(self.name, self._speed))

    return self._speed

    class Bird(Animal):

    def init(self,name,speed,color,genre):

    super().init(name,speed)

    self.color = color

    self.genre = genre

    # 重写方法

    def getSpeedBehavior(self):

    print(‘flying speed of %s is %s’ %(self.name, self._speed))

    return self._speed

    manager2.py 模块如下:

    # manager2.py 模块

    import time

    from animal2 import (Animal,Cat,Bird)

    class Manager():

    def init(self,animal):

    self.animal = animal

    def recordTime(self):

    self.__t = time.time()

    print(‘feeding time for %s is %.0f’%(self.animal.name,self.__t))

    self.animal.getSpeedBehavior()

    def getFeedingTime(self):

    return ‘%0.f’%(self.__t,)

    recordTime方法非常清爽,不需要任何if逻辑,只需要调用我们定义的Animal类的基方法getSpeedBehavior即可。

    在使用上面所有类时,Manager(jiafeimao)传入Cat类实例时,recordTime方法调用就被自动指向Cat实例的getSpeedBehavior方法;

    Manager(haiying)传入Bird类实例时,自动指向Bird实例的getSpeedBehavior方法,这就是多态和它的价值,Manager类的方法不必每次都修改,保证了类的封装性。

    if name == “main”:

    jiafeimao = Cat(‘jiafeimao’,2,‘gray’,‘CatGenre’)

    haiying = Bird(‘haiying’,40,‘blue’,‘BirdGenre’)

    Manager(jiafeimao).recordTime()

    print(’#’*30)

    Manager(haiying).recordTime()

    展开全文
  • 多态

    2020-03-27 11:34:26
    《第三章 多态》 polymorphism 多态 instance 例子 override 重载 constructor 构造器 ClassCastException 类型转换异常 upcasting 上抛 downcasting 向下转换 abstract 抽象 1.多态 是具有表现多种形态的能力的...
  • 多态 多态的定义、条件及案例 多态:同一个方法调用,由于对象不同会产生不同的行为 一个对象的实际类型是确定的,但可以指向对象的引用的类型很多 多态存在的条件: 有继承关系; 子类重写父类方法; 父类...
  • 静态多态和动态多态

    千次阅读 2017-03-16 16:08:57
    多态是发散式的,让相同的实现代码应用于不同的场合。 动多态是收敛式的,让不同的实现代码应用于相同的场合。 思维方式上: 静多态是泛型式编程风格,它看重的是算法的普适性。 动多态是对象式编程...
  • 多态详细讲解

    2020-11-22 23:34:05
    【1】多态跟属性无关,多态指的是方法的多态,而不是属性的多态。 【2】案例代入: public class Animal {//父类:动物: public void shout(){ System.out.println("我是小动物,我可以叫。。。"); } } public ...
  • 多态和动多态

    2019-09-26 14:32:29
    多态性可按照发生的时间段分为静多态(Static Polymorphism)和动多态(Dynamic Polymorphism)。其中静多态就是绑定发生在编译期(compile-time),此种绑定称为静态绑定static-binding);而动多态就是绑定发生在...
  • 【C++】virtual 与多态

    2020-03-09 19:48:29
    1 前言 The virtual keyword declares a virtual function or a virtual base class....多态(Polymorphism):当用于面向对象编程的范畴时,多态性的含义是指程序能通过引用或指针的动态类型获...
  • 类型转换的主要应用场合 赋值转换:将右边类型转化为左边类型 方法调用转换:将实参类型转化为形参类型 算术表达式转换:一个表达式中包含不同类型的操作数,将它们都转化为相同的类型再运算 字符串转换:字符串...
  • final 多态

    2020-06-26 22:23:21
    如果子类中存在与父类非私有的方法名,参数列表相同的方法 要求返回值也一模一样 权限修饰符要求子类不能比父类(权限更小) 这种现象称为“方法重写(override)” 重写的应用点: 子类要重新实现父类的某些功能 ...
  • 深入理解Java多态机制

    2017-08-31 19:28:52
    目录: 1,多态的概念? 2,存在的条件? 3,案列解析? 4,应用场景? 无太多文字赘述,通过案例驱动深入理解java多态机制,并且到各种场合中。
  • java多态

    2020-05-12 17:28:48
    多态可以使用户的应用程序具有可扩展性 理解 多态就是同一种行为具有多种表现形式的特征 好比生活中的手机,由于拨打的电话号码不同可以拨给不同的人,如拨打110是报警电话119是火警电话等。 java中多态的实现 ...
  • 方法的重写与多态

    2021-05-05 23:46:44
    方法的重写与多态 方法的重写 ​ 方法重写也叫方法覆盖,是指子类根据需求对从父类继承的方法进行重新编写。通常父类的方法被子类继承后,在不同的子类中可能需要做不同的操作。方法只能在子类中进行重写。 ​ 重写...
  • 描述Java三大特性中的多态 0 简述 多态就是多种状态:同一个行为,不同的子类表现出来不同的形态。 多态指的就是同一个方法调用,然后由于对象不同会产生不同的行为。 多态的好处: 为了提高代码的扩展性,符合...
  • 静态多态与动态多态

    2018-02-12 17:13:07
    多态的字面含义:具有多种不同的形态。 关键字:重载/模版和虚函数 类型:编译期多态(静态多态,早绑定)和运行期多态(晚绑定) 编译期多态(重载/模版): 重载 int getMax(int param1,int param2); double getMax...
  • 3、在运行时父类或接口的应用变量可以引用其子类的对象 多肽的作用: 1、多肽通过分离做什么和怎么做,从一个角度将接口和实现进行分离 2、多肽消除了类型之间的耦合关系 3、多肽的存在提高了程序的拓展性和后期的...
  • 多态的概念: 多态性是指同一个操作作用于某一类对象,可以有不同的解释,产生不同的执行结果。 多态存在的三个必要条件: ① 需要存在继承或实现关系 ② 同样的方法调用而执行不同的操作、运行不同代码(重写) ③...
  • 为什么要用多态

    2019-09-30 22:00:41
    多态是OOP(面向对象编程)的一项重要...下面看一个应用场景,一个软件要实现下面功能:用户在界面上添加各种几何图形(圆,三角形和正方形),用户可以以任意顺序、任意数量(当然内存不要溢出即可)添加上述几何图...
  • 实验任务任务一:图形面积周长计算小程序任务二:饲养员喂养动物程序实验内容:任务一: 图形面积周长计算任务目的:掌握多态的含义及应用场合掌握上转型对象和多态的实现掌握abstract关键字的使用任务描述:设计一...
  • 多态就是指不同的对象收到相同的消息,会产生不同的行为,同一个类在不同的场合下表现出不同的行为特征; 多态的作用:把不同的子类都看作是父类,可以屏蔽到不同子类对象之间的差异,写出通用的代码,做出通用的...
  • 深入理解多态

    2019-10-15 16:59:23
     抽象类的应用场合: 父类提供一系列规定,约束子类的行为。  抽象方法与虚方法的区别: 抽象方法 虚方法 用 abstract 修饰 用 virtual 修饰 ...
  • C#--接口与多态

    2017-09-09 21:36:36
    .net 中接口的定义规范 使用关键字interface定义,接口类名称通常使用 ‘i’...接口简单应用 接口的特点:接口实现类中的方法缺少一个都不行,而且方法的定义必须和接口中方法定义的规范完全一致。 接口具有强制性

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 13,498
精华内容 5,399
关键字:

多态的应用场合