• 面向对象(多态)


    多态

    可以理解为事物存在的多种体现形态
    动物:猫,狗
    猫 x = new 猫();
    动物 x = new 猫();
    -----------------------------
    多态的体现:
    父类的引用指向了自己的子类对象
    父类 x = new 子类();
    父类是向上抽取的结果,动物 x = new 猫(); new出来的猫具有动物的所有抽象特征
    如,猫有动物所具有的吃,睡得抽象特征
    但是 猫 x = new 动物();就不行,一个动物对象不一定具有猫的特征
    --------------------------------
    好处:多态的出现大大提高了程序拓展性
    ---------------------------------
    前提:必须是类与类之间有关系,要么继承,要么实现
    还有一个前提,就是存在覆盖,即,父类里面有个吃饭,
    但是子类必须覆盖父类的吃饭,如,猫吃鱼,狗吃骨头
    ---------------------------------
    弊端:提高了扩展性,但是只能使用父类的引用访问父类中的成员
    public class Test {
        public static void main(String[] args) {
            Animal a = new Mao();
            a.eat();
            a.catchMouse();--------------->这句代码是会报错的,因为它是猫特有的
        }
    }
     
    abstract class Animal{
        abstract void eat();
        }
     
    class Mao extends Animal{
        public void eat(){System.out.println("吃鱼");}
        public void catchMouse(){System.out.println("抓老鼠");}
        }
    -------------------------------------------------

    向上转型

    -------------------------------------------------------
    多态的实例
    abstract class Student
    {
        public abstract void study();
        public void sleep()
        {
            System.out.println("躺着睡");
        }
    }
    ————————————————
    class DoStudent
    {
        public void doSome(Student stu)
        {
            stu.study();
            stu.sleep();
        }
    }
    ————————————————
    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  DuoTaiDemo3
    {
        public static void main(String[] args) 
        {
            DoStudent ds = new DoStudent();
            ds.doSome(new BaseStudent());
            ds.doSome(new AdvStudent());
     
    //        BaseStudent bs = new BaseStudent();
    //        bs.study();
    //        bs.sleep();
    //        AdvStudent as = new AdvStudent();
    //        as.study();
    //        as.sleep();
        }
    }
    先看注释部分,由于基础班和高级班睡觉方式不同,
    所以我要分别实例化,并调用学习,睡觉的方法
    这样每次都调用学习,睡觉的方法,就会麻烦
    那么,此时就可以通过DoStudent类去管理这些事
    class DoStudent
    {
        public void doSome(Student stu)
        {
            stu.study();
            stu.sleep();
        }
    }
    new一个DoStudent,然后调用doSome()方法
    看,doSome方法参数是Student类型的,
    但实例化的时候,我可以new avd,base
    Student———>BaseStudent
    这样,我就实现了向上转型
    ------------
    上面的好处是什么呢,可以提高拓展性
    当我想开设一个黑客班的时候,只需要黑客班继承抽象类
    复写抽象类的方法,就可以用DoStudent来实例化了
    ----------------------------------------------------------------------------------
    如下图,zi类继承了fu类的method1,method2方法,并复写了method1方法
    现在Fu f = new Zi();
        f.method1();
        f.method2(); 
        //f.method3(); 如果加上这句,编译会失败的,因为编译看左边,左边是Fu,而Fu类中没有定义method3
    而运行看右边,就是说,调用方法时,要看Zi类的方法
    所以,上面运行结果是zi method_1;(子类复写的父类)
    fu method_2;(子类继承的父类)
    ---------------------------------------------------
    面试题
    多态中,成员变量的特点:无论编译和运行,都参考左边
    ------------------------------------------
    -------------------------------------------
    参考左边的话,那么打印的第一行就会打印父类的num——>5
    第二行就会打印子类的num——>8
    ----------------------------------------------
    多态中,静态成员的特点,都参考左边(静态的方法,变量)
    也就是说,子类重写父类的静态方法是不起作用的
    ---------------------------------------------------
    看下面是方法区,里面的是静态方法区,和非静态方法区
    --------------------------------------------------------------------------
    实例
    /*
    需求:
    电脑运行实例,
    电脑运行基于主板。主板上插网卡,声卡,,,,
    怎么插呢?通过PCI插槽这个标准
    */
    ————————————
    怎么弄呢
    首先,我要有一个主板,并把主板跑起来2
    然后,我的主板上要有PCI插槽,所以定义usePCI( PCI p);
    而PCI是一个标准,所以是接口
    这样,我的主板的PCI插槽里,就可以插声卡,网卡了。。。
    那我的声卡,网卡怎么定义呢,要遵循PCI标准,所以要实现PCI接口,并复写接口里的方法
    class NetCard implements PCI{
    run(){}
    close(){}
    }
    然后看main函数中是怎么跑起来的:
    先实例化一个主板,调用run方法让主板跑起来
      mb.usePCI(null);//这句代码会出错的,因为这里面是空引用,没有实例(修改后的代码已经有了判断,判断是否为空)
    注意:调用usePCI(new NetCard),参数是网卡,但定义的参数是PCI接口,这是怎么回事呢
    这是接口型引用指向自己的子类对象,而new的网卡实现了PCI接口(或者说标准)
    粗暴点说就是:只要你按照我的标准做(实现接口),你做出来的东西(实例化),就能插进我主板(MainBoard)上的PCI插槽(usePCI)里
    MainBoard mb = new MainBoard();
            mb.run();
            mb.usePCI(null);
            mb.usePCI(new NetCard());
     
     
    ————————————1
    interface PCI
    {
        public void open();
        public void close();
    }
    ————————————2
    class MainBoard
    {
        public void run()
        {
            System.out.println("mainboard run ");
        }
        public void usePCI(PCI p)    //PCI p = new NetCard()//接口型引用指向自己的子类对象。
        {
            if(p!=null)
            {
                p.open();
                p.close();
            }
        }
    }
    ——————————————3
    class NetCard implements PCI
    {
        public void open()
        {
            System.out.println("netcard open");
        }
        public void close()
        {
            System.out.println("netcard close");
            method();
        }
    }
    ——————————————4
    class SoundCard implements PCI
    {
        public void open()
        {
            System.out.println("SoundCard open");
        }
        public void close()
        {
            System.out.println("SoundCard close");
        }
    }
    ————————————————5
    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());
     
        }
    }
    ———————————————————————————————
    实例
    看截图,数据库的操作,我刚开始是使用JDBC连接数据库,并添加,删除数据的
    可是多年之后,随着技术的发展,出现了新的连接数据库的技术Hibernate
    那我可能就要根据需要,把所有的JDBC连接方式全改掉,这样的耦合性(粘性)太高了
    那么该怎么办呢
    思路是这样的,我可以定义一个标准(接口)UserInfoDao,而JDBC,Hibernate都是遵循这个标准的
    这个例子我主要是说实例化的过程
    UserInfoDao uid = new JDBC();这种形式
    接口  uid  = new 类名();        这个类实现了这个接口
    ————————————————————
    public class ExtendsDemo {
        public static void main(String[] args) {
        UserInfoDao uid = new JDBC();
        uid.add(new User());
        uid.delete(new User());
        }
    }
    ————————————
    class User{
        User(){
            System.out.println("new user sss");
        }
    }
    ————————————
    interface UserInfoDao
    {
        void add(User user);
     
        void delete(User user);
    }
    ————————————
    class JDBC implements UserInfoDao{
        public void add(User user){System.out.println("JDBC,,,,ADD");}
        public void delete(User user){System.out.println("JDBC,,,DELETE");}
    }
    ————————————
    class Hibernate implements UserInfoDao{
        public void add(User user){System.out.println("Hibernate,,,,ADD");}
        public void delete(User user){System.out.println("Hibernate,,,DELETE");}
    }
    ————————————
     
     
  • 相关阅读:
    阅读《Android 从入门到精通》(29)——四大布局
    UISegmentedControl 修改字体大小 和 颜色
    UITableView Scroll to top 手动设置tableview 滚动到 顶部
    xcode arc 下使用 block警告 Capturing [an object] strongly in this block is likely to lead to a retain cycle” in ARC-enabled code
    iOS key value coding kvc在接收json数据与 model封装中的使用
    NSData 转 bytes 字节数据
    git commit 出现 changes not staged for commit 错误
    iOS exit(),abort(),assert()函数区别
    ios 程序发布使用xcode工具Application Loader 正在通过ITUNES STORE进行鉴定错误
    iOS mac添加证书 不能修改“System Roots”钥匙串错误
  • 原文地址:https://www.cnblogs.com/aisi-liu/p/4164417.html
Copyright © 2020-2023  润新知