java多态--08

来源:互联网 发布:程序员是吃青春饭的吗 编辑:程序博客网 时间:2024/03/29 21:48

多态

可以理解为事物存在的多种体现形式

人:男人,女人
动物:猫,狗
猫 x = new 猫();
动物 x = new 猫();

1,多态的体现
父类的引用指向了自己的子类对象。
父类的引用也可以接收自己的子类对象
2,多态的前提
必须是类与类之间有关系,要么继承,要么实现。
通常还有一个前提,就是存在覆盖。
3,多态的好处
多态的出现,提高了程序的扩展性
弊端:只能使用父类的引用访问父类中的成员

abstract class Animal{    abstract void eat();    {        System.out.println("睡觉");    }}class Cat extends Animal{    public void eat()    {        System.out.println("吃鱼");    }    public void catchMouse()    {        System.out.println("抓老鼠");    }}class Dog extends Animal{    public void eat()    {        System.out.println("吃骨头");    }    public void kanjia()    {        System.out.println("wangwang");    }}class Pig extends Animal{    public void eat()    {        System.out.println("饲料");    }    public void gongdi()    {        System.out.println("拱地");    }}class DuoTaiDemo{    public static void main(String[] args)    {        function(new Cat());        function(new Dog());        function(new Pig());    }       public static void function(Animal a)//Animal a = new Cat();多态的体现    {        a.eat();    }}

这里写图片描述

构造代码快先执行。

父类引用指向子类对象
Animal a = new Cat();//类型提升,向上转型
a.eat();

如果想要调用猫的特有方法,如何操作?
强制将父类的引用,转成子类类型。向下转型。
Cat c = (Cat)a;
c.catchMouse();

千万不要出现这样的操作,就是将父类对象转成子类类型。
我们能转换的是父类引用指向自己子类的对象时,该引用可以被提升,也可以被强制转换。
多态自始至终都是子类对象在做着变化。
Animal a = new Animal();
Cat c = (Cat)a;

abstract class Animal{    abstract void eat();}class Cat extends Animal{    public void eat()    {        System.out.println("吃鱼");    }    public void catchMouse()    {        System.out.println("抓老鼠");    }}class Dog extends Animal{    public void eat()    {        System.out.println("吃骨头");    }    public void kanjia()    {        System.out.println("wangwang");    }}class Pig extends Animal{    public void eat()    {        System.out.println("饲料");    }    public void gongdi()    {        System.out.println("拱地");    }}class DuoTaiDemo2{    public static void main(String[] args)    {        //Animal a = new Cat();//类型提升,向上转型        //a.eat();        //如果想要调用猫的特有方法,如何操作?        //强制将父类的引用,转成子类类型。向下转型。        //Cat c = (Cat)a;        //c.catchMouse();        //千万不要出现这样的操作,就是将父类对象转成子类类型。        //我们能转换的是父类引用指向自己子类的对象时,该引用可以被提升,也可以被强制转换。        //多态自始至终都是子类对象在做着变化。        //Animal a = new Animal();        //Cat c = (Cat)a;        function(new Dog());        function(new Cat());    }    public static void function(Animal a)//Animal a = new Cat();    {        a.eat();        if(a instanceof Cat)//实例是否属于        {            Cat c = (Cat)a;            c.catchMouse();        }        else if(a instanceof Dog)        {            Dog c = (Dog)a;            c.kanjia();        }        else         {            Pig  p = (Pig)a;            p.gongdi();        }    }}

4,多态的应用

基础班
学习,睡觉
高级班
学习,睡觉
可以将这两类事物进行抽取

abstract class Student{    public abstract void study();    public void sleep()    {        System.out.println("躺着睡");    }}class BaseStudent extends Student{    public void study()    {        System.out.println("base study");    }    public void sleep()    {        System.out.println("坐着睡");    }}class AdvStudent extends Student{    public void study()    {        System.out.println("adv study");    }}class DoStudent{    public void dosome(Student stu)    {        stu.study();        stu.sleep();    }}class DuoTaiDemo3{    public static void main(String[] args)    {        DoStudent ds = new DoStudent();        ds.dosome(new BaseStudent());        ds.dosome(new AdvStudent());    }}

这里写图片描述

5,多态的出现代码中的特点(多态使用的注意事项)

在多态中成员函数(非静态)的特点:
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过。如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法。
简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。

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

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

class Fu{    static int num = 5;//成员变量    void method1()    {        System.out.println("fu method-1");    }    void method2()    {        System.out.println("fu method-2");    }    static void method4()//静态成员函数    {        System.out.println("fu method-4");    }}class Zi extends Fu{    static int num = 8;    void method1()    {        System.out.println("zi method-1");    }    void method3()    {        System.out.println("zi method-3");    }    static void method4()    {        System.out.println("zi method-4");    }}class DuoTaiDemo4{    public static void main(String[] args)    {        //Fu f = new Zi();        //System.out.println(f.num);        //Zi z = new Zi();        //System.out.println(z.num);//成员变量的特点,编译运行都看左边所属的类        //Fu f = new Zi();        //f.method1();        //f.method2();        //f.method3(); //会编译失败   //成员函数的特点(非静态)编译时看左边,左边类中没有这个方法就失败        Fu f = new Zi();        System.out.println(f.num);        f.method4();        Zi z = new Zi();        z.method4();               //静态成员函数特点,都参考左边        //Zi z = new Zi();        //z.method1();        //z.method2();        //z.method3();    }}

需求:
电脑运行实例
电脑运行基于主板

interface PCI{    public void open();    public void close();}class MainBoard{    public void run()    {        System.out.println("mainboard run");    }    public void usePCI(PCI p)//接口型引用指向自己的子类对象    {        if(p!=null)//PCI p = new NetCard()        {            p.open();            p.close();        }    }}class NetCard implements PCI{    public void open()    {        System.out.println("netcard open");    }    public void close()    {        System.out.println("netcard close");    }}class SoundCard implements PCI{    public void open()    {        System.out.println("soundcard open");    }    public void close()    {        System.out.println("soundcard close");    }}class DuoTaiDemo5{    public static void main(String[] args)    {        MainBoard mb = new MainBoard();        mb.run();        mb.usePCI(null);        mb.usePCI(new NetCard());        mb.usePCI(new SoundCard());    }}

这里写图片描述

Object类

Object:所有类的直接或间接父类
该类中定义的肯定是所有对象都具备的功能。

class Demo //extends Object{}class ObjectDemo{    public static void main(String[] args)    {        Demo d1 = new Demo();        Demo d2 = new Demo();        Demo d3 = d1;        System.out.println(d1.equals(d3));        System.out.println(d1==d2);        System.out.println(d1==d3);    }}

这里写图片描述

Object中已经提供了对对象是否相同的比较方法。
如果自定义类中也有比较相同的功能,没有必要重新定义,
只要沿袭父类中的功能,建立自己特有的比较内容即可。这就是覆盖。

class Demo //extends Object{    private int num;    Demo(int num)    {        this.num = num;    }    public boolean equals(Object obj)//Object obj = new Demo();    {        if(!(obj instanceof Demo))//判断是否所属同类            return false;        Demo d = (Demo)obj;       //向下转型        return this.num == d.num;    }}class ObjectDemo{    public static void main(String[] args)    {        Demo d1 = new Demo(4);        Demo d2 = new Demo(4);        System.out.println(d1.equals(d2));    }}

toString
获取对象的哈希值(16进制表现形式)。

class Demo{    Demo()    {}}class ObjectDemo{    public static void main(String[] args)    {        Demo d = new Demo();        System.out.println(Integer.toHexString(d.hashCode()));        System.out.println(d.toString());    }}

这里写图片描述

0 0
原创粉丝点击