zoukankan      html  css  js  c++  java
  • 《多态》

    【15-1】面向对象-多态-好处&弊端&前提
    
    //描述狗
    class Dog extends Animal
    {
        public void eat()
        {
            System.out.println("吃饭");
        }
    
        public void lookHome()
        {
            System.out.println("看家");
        }
    }
    
    //描述猫
    class Cat extends Animal
    {
        public void eat()
        {
            System.out.println("鱼");
        }
    
        public void catchMice()
        {
            System.out.println("抓老鼠");
        }
    }
    
    //进行抽取,将共性的功能抽取到父类Animal中。
    abstract class Animal
    {
        public abstract void eat();
    }
    
    class DogAndCatTest
    {
        public static void main(String[] agrs)
        {
            //Dog d = new Dog();
            //method(d);
    
            Animal a = new Dog();
            method(a);
            
    
            //Cat c = new Cat();
            method(new Cat());
        }
    /*
    发现,每一个动物,都需要为这个动物单独定义一个功能。
    让这个动物的对象去做事。
    这个程序扩展性很差。
    如何提高这个扩展性呢?
    发现,既然是让动物去吃,无论是Dog还是Cat,
    eat是它们的共性,于是就可以将eat进行抽取,抽取到父类中。
    
    Dog是Animal中的一种。
    Dog d = new Dog();
    Ainmal a = new Dog();
    Cat c = new Cat();
    Animal aa = new Cat();
    */
    
    //只要去建立Animal的引用,就可以接收所有的dog对象进来,让它们去eat
    //提高了程序的扩展性。
    
    
    public static void method(Animal a)
    {
        a.eat();
    }
    
    /*
    
    //接收Dog,让dog去做事
        public static void method(Dog d)
        {
            d.eat();
        }
    
    //接收Cat让Cat去做事
        public static void method(Cat c)
        {
            c.eat();
        }
        
    */
    
    }
    
    ========================================================================================================
    //15-2的完整例子如下:
    
    //抽象类 动物
    abstract class Animal
    {
        public abstract void eat();
    }
    
    //描述Dog
    class Dog extends Animal
    {
        public void eat()
        {
            System.out.println("吃饭");
        }
        public void lookHome()
        {
            System.out.println("看家");
        }
    }
    
    //描述猫
    class Cat extends Animal
    {
        public void eat()
        {
            System.out.println("鱼");
        }
        public void catchMice()
        {
            System.out.println("抓老鼠");
        }
    }
    
    
    class DuoTaiTest
    {
        public static void main(String[] args) 
        {
            //Dog d = new Dog();
            //method(d);
            //Cat c = new Cat();
            //method(c);
            Animal a = new Dog();
            //method(a);
            a.eat();
            //Animal a1 = new Dog();
            //method(a1);
            if(a instanceof Dog)
            {
                Dog d = (Dog)a;
                d.lookHome();
            }
            
        }
        //public static void method(Animal a)
        //{
        //    a.eat();
        //}
    }
    ===========================================================================================================15-2】面向对象-多态-转型
        //描述狗
    class Dog extends Animal
    {
        public void eat()
        {
            System.out.println("吃饭");
        }
    
        public void lookHome()
        {
            System.out.println("看家");
        }
    }
    
    //描述猫
    class Cat extends Animal
    {
        public void eat()
        {
            System.out.println("鱼");
        }
    
        public void catchMice()
        {
            System.out.println("抓老鼠");
        }
    }
    
    //进行抽取,将共性的功能抽取到父类Animal中。
    abstract class Animal
    {
        public abstract void eat();
    }
    
    /*
    多态:体现
        父类的引用或者接口指向了自己的子类对象。
        Dog d = new Dog();  //Dog对象的类型是Dog类型。
        Animal a = new Dog(); //Dog对象的类型右边是Dog类型,左边是Animal类型。
        
        好处:
        提高了程序的扩展性。
    
        弊端:
        通过父类引用操作子类对象时,只能使用父类中已有的方法,不能操作子类特有的方法。
    
        前提:
        1,必须有关系,继承或实现。
        2,通常都有重写操作
    
        子类的特有方法如何调用呢?
        Animal a = new Dog(); //Animal是父类型,new Dog()是子类对象。
        但是父类型引用指向子类对象时,这就是让子类对象进行了类型的提升(向上转型),
        如果想要使用子类的特有方法,只有子类型可以用。
        可以向下转型,强制转换。
        Animal a = new Dog();
        a.eat();
        Dog d = (Dog)a;//将a转型为Dog类型。向下转型
        d.lookHome();  //此时就可以用这个子类的特有功能了。
        向下转型什么时候用?当需要使用子类型的特有内容时。
    
        注意:无论向上还是向下转型,最终都是子类对象做着类型的变化。
    
        向下转型的注意事项:
        Animal a = new Dog();
        //Cat c = (Cat)a; //向下转型因为不明确具体子类对象类型,所以容易引发ClassCastException异常。
        所以为了避免这个问题,需要在向下转型前,做类型判断。
    
        判断类型用的是关键字。instanceof
        if(a instanceof Cat) //a指向的对象类型是Cat类型。
        {
            //将a转型为Cat类型。
            Cat a = (Cat)a;
            c.catchMouse();
        }
        else if(a instanceof Dog)
        {
            Dog d = (Dog)a;
            d.lookHome();
        }
    
    
        转型总结
        1,什么时候向上转型呢?
            提高程序的扩展性,不关心子类型(子类型被隐藏)
            需要用子类的特有的方法吗?不需要,那就向上转型。
        2,什么时候使用向下转型呢?
            需要使用子类特有的方法时。
            但是一定要使用instaceof 进行类型的判断,避免发生ClassCastException异常
    
    
    
    */
    
    class DogAndCatTest
    {
        public static void main(String[] agrs)
        {
            Dog d = new Dog();
            
            method(d);
    
            Cat c = new Cat();
            method(c);
        }
    
        public static void method(Animal a)
        {
            a.eat();
        }
    }
    
    
    
    
    【15-2】面向对象-多态-举例
    
        //多态-举例
    class 毕姥爷
    {
        public void 讲课()
        {
            System.out.println("讲管理");
        }
        public void 钓鱼()
        {
            System.out.println("钓鱼");
        }
    }
    
    class 毕老师 extends 毕姥爷
    {
        public void 讲课()
        {
            System.out.println("Java");
        }
        public void 看电影()
        {
            System.out.println("看电影");
        }
    }
    
    class DuoTaiTest
    {
        public static void main(String[] args)
        {
            毕姥爷 x = new 毕老师();
            x.讲课();
            x.钓鱼();
            //x.看电影();//不行
            //想要使用毕老师的特有方法时,需要
            if(x instanceof 毕老师)
            {
                毕老师 y = (毕老师)x;
                y.看电影();
            }
        }
    }
    
    -----------------------------------------15-3】面向对象-多态-练习-笔记本电脑
    =========================================================================================================
        //描述笔记本,用到了鼠标的功能。
    class noteBook
    {
        public void run()
        {
            System.out.println("notebook run");
        }
    
        public void useMouse(Mouse m)
        {
            if(m!=null)
            {
                m.open();
                m.close();
            }
        }
    }
    
    //描述鼠标。
    class Mouse
    {
        public void open()
        {
            System.out.println("mouse open");
        }
        public void close()
        {
            System.out.println("mouse close");
        }
    }
    
    
    class NoteTest 
    {
        public static void main(String[] args) 
        {
            noteBook b = new noteBook();
            b.run();
            b.useMouse(new Mouse());
        }
    }
    ==========================================================================================
        /*
    阶段一需要,笔记本电脑运行。
    按照面向对象的思想,用代码体现。
    名称提炼法。
    笔记本电脑。
        行为,运行。
    
    class HoteBook
    {
        //运行功能
        public void run()
        {
            System.out.println("notebook run");
        }
    }
    
    阶段二需求:想要在笔记本电脑上加上一个手提式鼠标。
    多了个对象,鼠标。
        行为:开启,关闭。
    
    class Mouse
    {
        public void open()
        {
            System.out.pritnln("mouse open");
        }
        public void close()
        {
            System.out.println("mouse close");
        }
    }
    
    
    
    //笔记本怎么用这鼠标呢?
    在笔记本中多一个使用鼠标的功能.
    需要修改原来的笔记本类中的内容,添加一个功能。
    
    class NoteBook
    {
        //运行功能
        public void run()
        {
            System.out.println("notebook run");
        }
    
        //使用鼠标的功能
        public void useMouse(Mouse m)
        {
            if(m!=null)
            {
                m.open();
                m.close();
            }
        }
    }
    
    //如果想要加入键盘呢?
    */
    class Mouse
    {
        public void open()
        {
            System.out.println("mouse open");
        }
        public void close()
        {
            System.out.println("mouse close");
        }
    }
    class NoteBook
    {
        //运行功能
        public void run()
        {
            System.out.println("notebook run");
        }
    
        //使用鼠标的功能
        public void useMouse(Mouse m)
        {
            if(m!=null)
            {
                m.open();
                m.close();
            }
        }
    }
    class DuoTaiTest2
    {
        public static void main(String[] args) 
        {
            NoteBook book = new NoteBook();
            book.run();
            book.useMouse(new Mouse());
            
        }
    }
    --------------------------------------------15-4】面向对象-多态-成员变量&成员函数&静态函数的特点
    ===================================================================================================
    /*
    多态中,成员调用的特点。
    
    1,成员变量。
        当子父类中出现了同名的成员变量时,
            多态调用该变量时。
                编译时期,参考的是引用变量所属的类中是否有被调用的成员变量,没有,编译失败。
                运行时期,也是调用引用变量所属的类中的成员变量。
    
            简单记:编译和运行都参考等号左边
                    编译运行看左边
    
    2,成员函数。
         编译,参考左边,如果没有,编译失败。
         运行,参考右边的对象所属的类。
              编译看左边,运行看右边。如果子类没有和父类同名的那个函数,则运行的是父类的那个函数。
        
        对于成员函数是动态绑定对到对象上。
    
    3,静态函数。
        对于静态成员函数,编译和运行都参考左边。
    
        对于静态函数是静态的绑定到类上。
    */
    
    //结论:
    //对于成员变量和静态函数,编译和运行都看左边。
    //对于成员函数,编译看左边,运行看右边。
    
    class Fu
    {
        int num = 3;
        void show()
        {
            System.out.println("fu show run");
        }
    
        static void method()
        {
            System.out.println("fu static method run");
        }
    }
    class Zi extends Fu
    {
        int num = 5;
        void show()
        {
            System.out.println("zi show run");
        }
        static void method()
        {
            System.out.println("zi static method run");
        }
    }
    
    class DuoTaiDemo
    {
        public static void main(String[] args) 
        {
            /* 
            //测试成员变量的多态调用
            Fu f = new Zi();
            System.out.println(f.num);  //3
            Zi z = new Zi();
            System.out.println(z.num);  //5
            */
            
            /*
            //测试成员变量的多态调用
            Fu f = new Zi();
            f.show();   //结果:zi show run;
            */
    
            //测试静态函数的多态调用。
            Fu f = new Zi();
            f.method();
            
            //注意:真正开发静态方法是不会被多态调用的,因为静态方法不所属于对象,而是所属于类的。
            Fu.method();
        }
    
    }
  • 相关阅读:
    java 深克隆(深拷贝)与浅克隆(拷贝)详解
    设计模式之单例模式
    设计模式之工厂模式
    批量下载google 字体小工具
    LBPL--基于Asp.net、 quartz.net 快速开发定时服务的插件化项目
    测试
    WCF 生产json对外的接口
    四舍五入小算法 (以前写的,采用拆分)
    自己动手写控件(模仿mvc htmlhelper的类)
    步骤详解安装Apache web服务器
  • 原文地址:https://www.cnblogs.com/sun-/p/5208791.html
Copyright © 2011-2022 走看看