zoukankan      html  css  js  c++  java
  • 09-02 java 多态

    多态的前提、多态的特点

    /*
        多态:同一个对象(事物),在不同时刻体现出来的不同状态。
        举例:
            猫是猫,猫是动物。
            水(液体,固体,气态)。
            
        多态的前提:
            A:要有继承关系。
            B:要有方法重写。
                其实没有也是可以的,但是如果没有这个就没有意义。
                    动物 d = new 猫();
                    d.show();
                    动物 d = new 狗();
                    d.show();
            C:要有父类引用指向子类对象。
                父 f =  new 子();
                
        用代码体现一下多态。
        
        多态中的成员访问特点:
            A:成员变量
                编译看左边,运行看左边。
            B:构造方法
                创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化。
            C:成员方法
                编译看左边,运行看右边。
            D:静态方法
                编译看左边,运行看左边。
                (静态和类相关,算不上重写,所以,访问还是左边的)
                
            由于成员方法存在方法重写,所以它运行看右边。
    */
    class Fu {
        public int num = 100;
    
        public void show() {
            System.out.println("show Fu");
        }
        
        public static void function() {
            System.out.println("function Fu");
        }
    }
    
    class Zi extends Fu {
        public int num = 1000;
        public int num2 = 200;
    
        public void show() {
            System.out.println("show Zi");
        }
        
        public void method() {
            System.out.println("method zi");
        }
        
        public static void function() {
            System.out.println("function Zi");
        }
    }
    
    class DuoTaiDemo {
        public static void main(String[] args) {
            //要有父类引用指向子类对象。
            //父 f =  new 子();
            Fu f = new Zi();
            System.out.println(f.num);
            //找不到符号
            // System.out.println(f.num2);
            
            f.show();
            //找不到符号
            // f.method();
            f.function();
        }
    }

    多态的好处:

    /*
        多态的好处:
            A:提高了代码的维护性(继承保证)
            B:提高了代码的扩展性(由多态保证)
            
        猫狗案例代码
    */

    //父类,动物类
    class Animal { public void eat(){ System.out.println("eat"); } public void sleep(){ System.out.println("sleep"); } } class Dog extends Animal { public void eat(){ System.out.println("狗吃肉"); } public void sleep(){ System.out.println("狗站着睡觉"); } } class Cat extends Animal { public void eat() { System.out.println("猫吃鱼"); } public void sleep() { System.out.println("猫趴着睡觉"); } } class Pig extends Animal { public void eat() { System.out.println("猪吃白菜"); } public void sleep() { System.out.println("猪侧着睡"); } } //针对动物操作的工具类 class AnimalTool { private AnimalTool(){} //不管是什么对象,都是Animal类,这就叫多态拓展性 public static void useAnimal(Animal a) { a.eat(); a.sleep(); } } class test { public static void main(String[] args) { //我喜欢猫,就养了一只 Cat c = new Cat(); //我很喜欢猫,所以,又养了一只 Cat c2 = new Cat(); //我特别喜欢猫,又养了一只 Cat c3 = new Cat(); AnimalTool.useAnimal(c); AnimalTool.useAnimal(c2); AnimalTool.useAnimal(c3); System.out.println("--------------"); //我喜欢狗 Dog d = new Dog(); Dog d2 = new Dog(); Dog d3 = new Dog(); AnimalTool.useAnimal(d); AnimalTool.useAnimal(d2); AnimalTool.useAnimal(d3); System.out.println("--------------"); //我喜欢宠物猪 //定义一个猪类,它要继承自动物,提供两个方法,并且还得在工具类中添加该类方法调用 Pig p = new Pig(); Pig p2 = new Pig(); Pig p3 = new Pig(); AnimalTool.useAnimal(p); AnimalTool.useAnimal(p2); AnimalTool.useAnimal(p3); System.out.println("--------------"); } }

    多态的弊端

    /*
        多态的弊端:
            不能使用子类的特有功能。
    */
    class Fu {
        public void show() {
            System.out.println("show fu");
        }
    }
    
    class Zi extends Fu {
        public void show() {
            System.out.println("show zi");
        }
        
        public void method() {
            System.out.println("method zi");
        }
    
    }
    
    class DuoTaiDemo3 {
        public static void main(String[] args) {
            //测试
            Fu f = new Zi();
            f.show();
            f.method();//编译看左边,但是左边的Fu没有method方法,会报错。不能使用子类的method方法
        }
    }

    多态弊端的解决;

    /*
        多态的弊端:
            不能使用子类的特有功能。
            
        我就想使用子类的特有功能?行不行?
            行。
            
        怎么用呢?
            A:创建子类对象调用方法即可。(可以,但是很多时候不合理。而且,太占内存了)
            B:把父类的引用强制转换为子类的引用。(向下转型)
            
        对象间的转型问题:
            向上转型:
                Fu f = new Zi();
            向下转型:
                Zi z = (Zi)f; //要求该f必须是能够转换为Zi的。
    */
    class Fu {
        public void show() {
            System.out.println("show fu");
        }
    }
    
    class Zi extends Fu {
        public void show() {
            System.out.println("show zi");
        }
        
        public void method() {
            System.out.println("method zi");
        }
    
    }
    
    class DuoTaiDemo4 {
        public static void main(String[] args) {
            //测试
            Fu f = new Zi();
            f.show();
            //f.method();
            
            //创建子类对象
            //Zi z = new Zi();
            //z.show();
            //z.method();
            
            //你能够把子的对象赋值给父亲,那么我能不能把父的引用赋值给子的引用呢?
            //如果可以,但是如下
            Zi z = (Zi)f;
            z.show();
            z.method();
        }
    }

    多态问题的理解:

    多态的问题理解:
        class 孔子爹 {
            public int age = 40;
            
            public void teach() {
                System.out.println("讲解JavaSE");
            }
        }
        
        class 孔子 extends 孔子爹 {
            public int age = 20;
            
            public void teach() {
                System.out.println("讲解论语");
            }
            
            public void playGame() {
                System.out.println("英雄联盟");
            }
        }
        
        //Java特别火,很多人来请孔子爹去讲课,这一天孔子爹被请走了
        //但是还有人来请,就剩孔子在家,价格还挺高。孔子一想,我是不是可以考虑去呢?
        //然后就穿上爹的衣服,带上爹的眼睛,粘上爹的胡子。就开始装爹
        //向上转型
        孔子爹 k爹 = new 孔子();
        //到人家那里去了
        System.out.println(k爹.age); //40
        k爹.teach(); //讲解论语
        //k爹.playGame(); //这是儿子才能做的
        
        
        //讲完了,下班回家了
        //脱下爹的装备,换上自己的装备
        //向下转型
        孔子 k = (孔子) k爹; 
        System.out.println(k.age); //20
        k.teach(); //讲解论语
        k.playGame(); //英雄联盟

    多态继承中的内存讲解:

     多态中的对象变化内存图解:

    多态中类转换异常:

    /*
        ClassCastException:类型转换异常
        一般在多态的向下转型中容易出现
    */
    class Animal {
        public void eat(){}
    }
    
    class Dog extends Animal {
        public void eat() {}
        
        public void lookDoor() {
        
        }
    }
    
    class Cat extends Animal {
        public void eat() {
        
        }
        
        public void playGame() {
            
        }
    }
    
    class DuoTaiDemo5 {
        public static void main(String[] args) {
            //内存中的是狗
            Animal a = new Dog();
            Dog d = (Dog)a;
            
            //内存中是猫
            a = new Cat();
            Cat c = (Cat)a;
            
            //内存中是猫
            Dog dd = (Dog)a; //ClassCastException
        }
    }
    猫狗案例
    /*
        多态练习:猫狗案例
    */
    class Animal {
        public void eat(){
            System.out.println("吃饭");
        }
    }
    
    class Dog extends Animal {
        public void eat() {
            System.out.println("狗吃肉");
        }
        
        public void lookDoor() {
            System.out.println("狗看门");
        }
    }
    
    class Cat extends Animal {
        public void eat() {
            System.out.println("猫吃鱼");
        }
        
        public void playGame() {
            System.out.println("猫捉迷藏");
        }
    }
    
    class DuoTaiTest {
        public static void main(String[] args) {
            //定义为狗
            Animal a = new Dog();
            a.eat();
            System.out.println("--------------");
            //还原成狗
            Dog d = (Dog)a;
            d.eat();
            d.lookDoor();
            System.out.println("--------------");
            //变成猫
            a = new Cat();
            a.eat();
            System.out.println("--------------");
            //还原成猫
            Cat c = (Cat)a;
            c.eat();
            c.playGame();
            System.out.println("--------------");
            
            //演示错误的内容
            //Dog dd = new Animal();
            //Dog ddd = new Cat();
            
            //ClassCastException
            //Dog dd = (Dog)a;//这个编译不报错,运行才报错
        }
    }    
    不同地方饮食文化不同的案例
    /*
        不同地方饮食文化不同的案例
    */
    class Person {
        public void eat() {
            System.out.println("吃饭");
        }
    }
    
    class SouthPerson extends Person {
        public void eat() {
            System.out.println("炒菜,吃米饭");
        }
        
        public void jingShang() {
            System.out.println("经商");
        }
    }
    
    class NorthPerson extends Person {
        public void eat() {
            System.out.println("炖菜,吃馒头");
        }
        
        public void yanJiu() {
            System.out.println("研究");
        }
    }
    
    class DuoTaiTest2 {
        public static void main(String[] args) {
            //测试
            //南方人
            Person p = new SouthPerson();
            p.eat();
            System.out.println("-------------");
            SouthPerson sp = (SouthPerson)p;
            sp.eat();
            sp.jingShang();
            System.out.println("-------------");
            
            //北方人
            p = new NorthPerson();
            p.eat();
            System.out.println("-------------");
            NorthPerson np = (NorthPerson)p;
            np.eat();
            np.yanJiu();
        }
    }

    看程序,出结果:

    /*
        看程序写结果:先判断有没有问题,如果没有,写出结果
        
        多态的成员访问特点:
            方法:编译看左边,运行看右边。
            
        继承的时候:
            子类中有和父类中一样的方法,叫重写。
            子类中没有父亲中出现过的方法,方法就被继承过来了。
    */
    class A {
        public void show() {
            show2();
        }
        public void show2() {
            System.out.println("我");
        }
    }
    class B extends A {
        /*
        public void show() {
            show2();
        }
        */
    
        public void show2() {
            System.out.println("爱");
        }
    }
    class C extends B {
        public void show() {
            super.show();
        }
        public void show2() {
            System.out.println("你");
        }
    }
    public class DuoTaiTest4 {
        public static void main(String[] args) {
            A a = new B();
            a.show();
            
            B b = new C();
            b.show();
        }
    }
  • 相关阅读:
    vim配置
    git rebase
    mongodb的docker-compose.yml
    Nginx配置BrowserRouter跟随react-router
    Flux Architecture & Redux Data Flow & redux & react-redux PPT
    from acwing 从算法数量推算算法复杂度
    evalRPN 逆波兰算术
    二分区间
    Flex布局
    Treap 模板
  • 原文地址:https://www.cnblogs.com/baiyangyuanzi/p/6824359.html
Copyright © 2011-2022 走看看