• 面向对象(继承、final关键字、抽象类、接口)


    继承(extends)
    如果父类中有的功能不应该是子类所具备的,那就不要继承
     
     
    ---------------------------------------------------------------------------------
    java只支持单继承,不支持多继承,但支持多层继承(a-->b-->c)
    为什么?
    如图,c继承a,b,调用show方法,因为a,b都有show方法,那不知道该调用谁啊
     
    --------------------------------------------------------------------------
    如果子类含有父类名称相同的变量,则会打印子类的,其实是省略了关键字this
    如果想打印父类的那个变量,则用关键字super修饰
     
     
    如图,子类中的num已经注释了,此时在打印num,则将打印父类的num,
    num即 super.num
    --------------------------------------------------------------------------
    重写(覆盖)
    如果子父类中有相同的方法,子类new一个对象调用该方法时,会运行子类的方法
    父类的方法其实也还在,只是没有运行
     
    通过super继承父类的内容,并拓展子类的功能
    如,子类不必在写number,而是继承父类的
    super.show();
    ----------------------------------------------------------------------------
    权限:private、  默认权限(什么也不写)、public
    注意:子类覆盖父类,必须保证子类权限大于父类权限
    如图,子父类的speak方法不能成为覆盖
    为什么呢,因为父类的speak方法为private,父类之外是看不见这个方法的,
    所以子类不知道父类有一个speak方法,所以怎么去覆盖啊

    重写和重载
    重载,同一个类,参数类型或者个数不同
    重写,不同类中,函数名,参数。。都相同,里面的内容不同
     
    注:覆盖必须和子类函数名等一模一样,只是内容不同(也可相同,但没意义啊)
    如 父类 int show()
    子类 void show()
    会报错,为什么,首先,show方法在子类中没有实现重写,因为返回值类型不同
    然后,子类中就会存在两个返回值类型不同的show方法,当调用。show时,
    系统不知道要调用哪个show方法
    -----------------------------------------------------------------------------
    上面这段代码输出的是:
    fu run;
    zi run;
    ---------------------------
    知道了子类构造函数里面都有一个隐式得得super();
    会调用父类的无参构造函数,那么,如果想调用父类的有参构造函数呢
    就用super(参数);
     
    看下面这个例子
    有参数的构造函数,一面已经有了this,就不能有super了
    其实this是调用的无参构造函数zi();
    而zi()里面的第一行默认是super,即调用父类的无参构造。。
    即,子类中至少会有一个构造函数去访问父类的构造函数
     

    为什么this(),super()不能同时在构造函数中,因为他们都在第一行
    为什么都在第一行,因为初始化动作要先做。。
    -----------------------------------------------------------------
    final
    目的是什么:为了保证有些东西不能被继承,就用final修饰

    如下面这个类,为最终类,就不能被继承
    --------------------------------
    3.被final修饰的方法不可以被复写
    上面整个类都不能被复写,但是如果我想让类中一部分方法可以被复写,
    另一部分可以被复写,那就用final修饰类中的方法
    如图,show2()可以被复写,show1()不能被复写
    ------------------------------------
    4.被final修饰的变量是一个常量,只能赋值一次,既可以修饰成员变量,也可修饰局部变量
    成员变量:
    final int x= 3;
    局部变量:
    void show(){
    final int num = 5;
    }
    那么,final用在什么地方呢,举个栗子
     final double PI = 3.14;
    常量的定义:所有字母大写,多个单词的话,单词之间下划线连接
    ---------------------------
    而final修饰的变量,前面通常会加一个修饰符static静态,因为静态的内容会被方法区中共享
    所以就是这种形式:public static final double PI = 3.14;
    ------------------------------
    目前学到的可以修饰类的修饰符有:
    public / final / 默认修饰符(什么都不加)
    ----------------------------------------------------------------------------------------
    抽象类
    抽象类大体上是用来继承的 -_-
    多个类中出现相同的功能,但是功能主体不同,这时可以上向抽取。
    这时,只抽取功能定义,而不抽取功能主体
    抽象类是怎么来的,举个栗子
    Person{
                void study(){
                    Syso("study");
        }
    }
     
    Student extends Person{
                void study(){
                    Syso("study");
        }
    }
    Worker extends Person{
                void study(){
                    Syso("worker");
        }
    }
    看上面三个类,学生,工人都继承人,都有study方法,但都不一样,
    所以,此时人类里定义的学习的方法体就没有任何意义了(因为一直被复写)
    所以,人类里的syudy方法就可以演变成:
    -->study(){}-->study();
    但是,成为这样子后,你看到这个方法,不知道具体是干嘛的(因为没有方法体)
    所以,可以定义为抽象
    abstract void study();
    抽象方法必须放在抽象类中
    abstract class Student{
        abstract void study();
    }
    -------------------------------------------------------
    抽象类特点:
    1.抽象方法一定在抽象类中
    2.抽象方法和抽象类都必须被abstract修饰
    3.抽象类不可以用new创建对象,即抽象类不可以实例化,因为调用抽象方法没有意义
    因为抽象方法两个方法体都没有,你调用它干啥
    4.抽象类中的抽象方法要被使用,子类必须复写抽象类中所有的抽象方法
    ----------------------------------------------------------------------
    那抽象类有什么用呢:
    抽象类就是定义一个框架,举个栗子
    老板说要开发一款手机,要有屏幕,有按键。。。
    但具体怎么做,老板不管
    abstract class 手机{
        abstract void 屏幕();
        abstract void 按键();
    }
    --------------------------
    抽象类可以强制子类去做些事情
    上面的例子,我如果在老板的公司做手机,我就必须弄个屏幕,弄个按键
    注:抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象(java类库中有这样的例子)
    抽象类中可没有抽象变量
    抽象类和普通类的区别就是:
    抽象类比一般类多了抽象函数;
    抽象类不可以被实例化
    ------------------------------------------------
    上面总结了没有抽象变量,但并不代表没有普通变量
    如图,抽象类中是可以有普通方法和变量的
    子类继承了抽象类之后,必须要重写抽象类的抽象方法sleep()
    --------------------------------------------------------------
    设计模式:
    模板方法设计模式
    什么是模版方法呢?
    在定义功能时,功能的一部分是确定的,但是有一部分是不确定,而确定的部分在使用不确定的部分,
    那么这时就将不确定的部分暴露出去。由该类的子类去完成。
    比如这个类,获取运行一段代码的时间
    中间的runcode方法是变化的内容,那么,就把runcode暴露出去,让别人根据需要复写
    SubTime这个类继承GetTime类,并实现抽象方法runcode()
    在main函数中,实例化SunTime类,调用父类的getTime方法
     
    --------------------------------------------------------------
    接口
    当抽象类中的方法都是抽象的,那么该类可以通过接口来表示
    class 用于定义类;
    interface用于定义接口
    注:接口中定义的是常量,
    所以要大写 public static final double PI = 3.14;
    ---------------------------------------------------
    接口的示例
    interface Inter
    {
        public static final int NUM = 3;
        public abstract void show();
    }
    看,我把接口中的成员定义成这个样子行不行啊
    答案是可以的,接口中的成员都有固定的修饰符,如果你没有加的话,
    系统也会自动给你加上,但是这样写不规范
    ---------------------------------------------------------
    接口也不能创建对象(因为有抽象方法),只能实现接口implements
    子类必须重写接口中的所有抽象方法才能实例化,否则,子类是一个抽象类
    ------------------------------------------------
    接口可以被类多实现-->即,一个类可以实现多个接口,即:多实现
    首先,java是不支持多继承的(一个类同时继承多个类),
    但是不支持的话有弊端,怎么弥补呢,就用接口的多实现弥补
    为什么多继承不能行,多实现就可以呢,因为
    多继承,可能会出现相同的方法名,但是,方法体不一样,不知道调用哪个;
    但是,多实现里面都是抽象方法,不会出现这种情况
    interface A
    { void methodA();
    }
    interface B 
    { void methodB();
    }
     
    class C implements A,B
    public void methodA(){}
    public void methodB(){}
    }
    ----------------------------------------
    一个类在继承另一个类(单继承)的同时,还能实现多个接口
    ------------------------------------------
    接口与接口之间也可以继承,可以实现多继承
    原理很简单,接口多继承不会出现类多继承那种同名函数,不同方法体不知调用谁的问题
    因为都是抽象方法。。。
    -----------------------------------
    如下图,接口C继承了接口 A,B
    类D实现了接口C
    那么,在类中,就要把A,B,C接口中的抽象方法都复写
    ---------------------------------
    下面这种情况是不允许出现的,
    接口A,B分别定义了返回值类型不同的show()方法,
    类D实现了A,B,那么,D就要分别重写两个返回值不同的show方法
    如果这样的话,那就遇到问题:当创建D的实例对象的时候,调用D的show方法,不知道该调用哪个
    所以,如果出现这样的定义,java会报错
     
     
    看到上面那个图片,别人问你的 java支持多继承吗
    你就可以机智的回答:java支持多继承,但是,仅限于接口与接口之间 呵呵~
    -----------------------------------------------------------
    接口和继承
    看代码,张三是学生,所以,它具备学生的共性;
    但是,至于抽烟这个接口,并不是所有学生都抽烟,
    所以,谁抽烟谁就实现抽烟接口
    即:基本功能定义在父类中,拓展功能定义在接口中
    abstract class Student
    {
        abstract void study();
        void sleep()
        {
            System.out.println("sleep");
        }
     
    }
     
    interface Smoking
    {
        void smoke();
    }
     
    class ZhangSan extends Student implements Smoking
    {
        void study(){}
        public void smoke(){}
    }
     
     
     
  • 相关阅读:
    git的使用
    模块化的 require 和 import的区别
    Javascript模块化编程(三):require.js的用法
    Javascript模块化编程(二)commonJS规范和AMD规范
    Javascript模块化编程发展历史
    GULP的使用流程
    jQuery事件对象
    jQuery文档处理 |
    Vue学习笔记【12】——过滤器
    Vue学习笔记【11】——Vue调试工具vue-devtools的安装步骤和使用
  • 原文地址:https://www.cnblogs.com/aisi-liu/p/4164385.html
Copyright © 2020-2023  润新知