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();
        }
    }
  • 相关阅读:
    hdu5360 Hiking(水题)
    hdu5348 MZL's endless loop(欧拉回路)
    hdu5351 MZL's Border(规律题,java)
    hdu5347 MZL's chemistry(打表)
    hdu5344 MZL's xor(水题)
    hdu5338 ZZX and Permutations(贪心、线段树)
    hdu 5325 Crazy Bobo (树形dp)
    hdu5323 Solve this interesting problem(爆搜)
    hdu5322 Hope(dp)
    Lightoj1009 Back to Underworld(带权并查集)
  • 原文地址:https://www.cnblogs.com/baiyangyuanzi/p/6824359.html
Copyright © 2011-2022 走看看