面向对象的三大特征

一、封装

    将类的某些信息隐藏在类内部,不允许外部程序直接访问(隐藏对象的信息)通过该类提供的方法来实现对隐藏信息的操作和访问(流出访问的接口)

    特点:1.只能通过规定的方法访问数据
               2.隐藏类的实例细节,方便修改和实现

    static关键字

        1、类属性(静态属性)
            1.类对象共享
            2.类加载时产生,销毁时释放。
            对象名.静态变量名
            类.静态变量名
            使用实例化后的对象操作时,会有黄色叹号警报,应直接用 类.静态变量名 调用。

        普通代码块
            在方法体中直接写 {} 顺序执行,先出现,先执行。

        构造代码块
            在类中直接写 {} 构造代码块是在类被创建时调用,先于构造方法

        静态代码块
            在类中直接写 static{} 类加载时调用,优先于构造代码块执行

        以上三个,当一个类多次实例化,静态代码块只执行一次,其他两种会执行多次。
        顺序:静态代码块→构造代码块→普通代码块

    2、类方法(静态方法)
        1.静态方法中不能直接访问同一个类中的非静态成员(方法和属性),只能直接调用静态成员
        2.静态方法中不能使用this,可以通过实例化调用其他方法

二、继承
    一种类与类之间的关系
    使用已存在的类的定义作为基础建立新类
    新类的定义(子类或言派生类)可以增加新的数据或新的功能,也可以用父类的功能,但不能选
        择性地继承父类(基类)
    即子类可以访问父类的非私有成员
    父类无法访问子类任何成员对象

    继承的关系
        满足"A is a B"的关系就可以形成继承关系
        一个子类只能继承一个父类
        继承优先于多态(父类引用优先于接口引用)

        特点:1.利用代码复用
                   2.缩短开发周期

    访问修饰符
        protected:允许在当前类、同包子类/非子类、跨包子类调用;跨包非子类不允许调用
        默认:允许在当前类、同包子类/非子类调用;跨包子类/非子类不允许调用
        大小顺序:private→默认→protected→public

    方法重载
        1、同一个类中
        2、方法名相同,参数列表不同(参数顺序、个数、类型)
        3、方法返回值、访问修饰符任意
        4、与方法的参数名无关

    方法重写
        1、有继承关系的子类中
        2、方法名相同,参数列表相同(参数顺序、个数、类型)
        3、访问修饰符,访问范围需要大于等于父类的访问范围
        4、与方法的参数名无关
        5、父类中的static方法不能被子类重写(如果子类和父类中有同名的static修饰的方法名时,则
                不为重写)

    子类与父类的加载顺序
        父类静态方法→子类静态方法→父类对象构造→子类对象构造

    父类构造方法
        父类的构造不允许被继承、不允许被重写,但是会影响子类对象的实例化

    子类构造方法
        子类构造默认调用父类无参构造方法
        可以通过super()调用父类允许被访问的其他构造方法
        super()必须放在子类构造方法有效代码第一行

    super
        1.子类的构造的过程中必须调用其父类的构造方法
        2.如果子类的构造方法中没有显式标注,则系统默认调用父类的无参的构造方法
        3.如果子类构造方法中既没有显式标注,且父类中没有无参的构造方法,则编译出错
        4.使用super调用父类指定构造方法,必须在子类的构造方法的第一行

        代表父类引用:
            1.访问父类成员方法super.方法名()
            2.访问父类属性super.属性名
            3.访问父类构造方法super();
        this和super都不能在静态方法中使用

    Object类
        Object类是所有类的父类
        一个类没有使用extends关键字明确标识继承关系,则默认继承Object类(包括数组)
        Java中的每个类都可以使用Object中定义的方法
        equals比较的是两个引用是否指向同一对象,==比较的是内部的值,当比较的为复合数据类型(类)比较的则是内存地址
        equals可以通过重写,改变比较的值
        toString
            1.输出对象名时,默认会直接调用勒种的toString
            2.继承Object中的toString方法时,输出对象的字符串表示形式:类型信息+@+地址信息
            3.子类可以通过重写toString方法的形式,改变输出的内容以及表现形式

    final关键字
        final 类,该类不可被继承
        final 方法,该方法不可被重写,但可以被子类继承使用
        final 方法内局部变量:只要在具体被使用之前进行赋值即可,一旦赋值不允许被修改
            变量成员属性
        赋值过程:
            1、定义直接初始化
            2、构造方法
            3、构造代码块
        final可配合static使用,类似于常量
        使用final修饰可以提高性能,但会降低可扩展性

多态:
    概念:允许不同类的对象对同一消息做出不同反应
    两种多态:1.编译时多态:设计时多态方法重载
                      2.运行时多态:程序运行时动态决定调用哪个方法(多数)
    必要条件:1.满足继承关系
                      2.父类引用指向子类对象

    向上转型(隐式转型、自动转型)
        父类引用指向子类对象可以调用子类重写的方法以及 父类派生的方法,无法调用子类独有方法
        注意:父类中的静态方法无法被子类重写,所以向上转型之后,只能调用到父类原有的静态方 
                  法
        小类转型为大类例如:父类 对象名=new 子类名();

    向下转型(强制类型转换)
        子类引用指向父类实例,此处必须进行强制转换,此时就可以调用子类特有的方法
        在使用向上转型之后才可以进行向下转型
        例如: 父类名 对象名=new 子类名();
                    子类名 对象名=(子类名)对象名(强转)
                    或者
                    子类名 对象名=new 父类名();
          https://blog.csdn.net/azhegps/article/details/53608994

    instanceof运算符
        用于判断该类是否是由该类实例化产生的
        极父类、父类、该类返回值都为true
        用法:对象名 instanceof 类名
        返回值:true/false

    抽象类:
        abstract 类名(){}
        当此类为抽象类时,不可被实例化,只能被继承,可以通过向上转型完成对象实例
        子类必须需要重写抽象父类中的方法,否则报错
        抽象类里可以没有抽象方法
        应用场景:某个父类只是知道其子类应该包含怎样的方法,但无法准确知道这些子类如何实现这些方法
        优点:1.限制了子类的设计随意性
                   2.阻止了无意义父类的实例化

    抽象方法:
        abstract 方法名();
        不允许包含方法体(不允许具体实现)子类必须重写父类的抽象方法,否则,子类也是抽象类
        包含抽象方法的类一定是抽象类
        static final private关键字都不可以与abstract并存的

    为什么要用抽象类、抽象方法
        1、子类的具体方法不需要在父类中实现,只需要在父类中建立一个抽象类,用来提醒程序员
        2、需要用抽象方法提醒程序员,必须实现这个方法(子类中重写)(随着每一个子类不同而实现自己的特征)

    接口
        作用:1、接口定义了某一批类所需要遵守的规范
                   2、接口不关心这些类的内部数据,也不关心这些类里方法的实现细节,它只规定这些类里必须提供某些方法
        格式:interface 类名()
                    {public void 方法名();}
                    接口名 对象名=new 类名();
        规则:1、类名以I 打头例如 I类名()
                   2、接口的访问修饰符为public
                   3、接口中抽象方法可以不写abstract关键字
                   4、访问修饰符默认public
                   5、当一个类实现接口时,此类必须重写接口中的所有方法体,否则需要将该类设置为
                         抽象类
                   6、而且以接口名 对象名=new 类名();这种样式的对象名不可以引用类中的方法体
                   7、接口中可以包含常量,默认为public static final,用接口名.常量名调用或者用实现接
                             口的类调用 对象名.常量名
                   8、对象名无法引用类中特有的方法体,
                   9、我们可以利用接口来描述不同的类型拥有相同的行为特征

    default
        默认方法,可以带方法体jdk1.8
        可以在实现类中重写,并可以通过接口的引用调用
        当实现类中实现多个接口,且接口中都有默认方法,必须在实现类中重写接口中的默认方法

    static
        静态方法,可以带方法体jdk1.8
        不可以在实现类中重写,可以用接口名调用
        接口名.super.静态方法名()

    多接口中重名常量
        当一个常量在一个类的父类和其多个接口中都有时,系统无法自行判断子类调用的是哪一个,只有在子类中重写该常量才不报错

    接口的继承
        接口也可以实现继承关系,并且一个接口可以继承多个父接口
        当父接口中有多个重名的方法时,子接口需要重写方法体避免出错

    内部类
        概念:1.在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类成为内部
                      类
                   2.与之对应,包含内部类的类被称为外部类
        为什么要使用内部类
            通过外部类访问外部类,提供了更好的封装手段
            内部类隐藏在外部类之内,更好的实现了信息隐藏
            不允许其他的类随意访问
        内部类与外嵌类的关系:
            1.内部类的外嵌类的成员变量在内部类中仍有效果,内部类中的方法也可以调用外嵌类中的
                方法
            2.内部类的类体中不可以声明类变量和类方法。外嵌类的累体重可以用内部类声明对象,作
                为外嵌类的成员
            3.内部类仅供它的外嵌类使用,其他类不可以用某个类的内部类声明对象
        内部类的分类
            成员内部类、静态内部类、方法内部类、匿名内部类
        成员内部类
            内部类中最常见的就是成员内部类,也成为普通内部类 class 内部类名{}
            特点:1.内部类在外部使用时,无法直接实例化,需要借助外部类信息才能完成实例化
                        方式一:外部类.内部类 对象名=new 外部类().new 内部类()
                        方式二:外部类对象.new 内部类
                        方式三:外部类对象.获取方法()
                       2.内部类的访问修饰符,可以任意,但是访问范围会受到影响
                       3.内部类可以直接访问外部类的成员;如果出现同名属性,优先访问内部类中定义的
                       4.可以使用 外部类.this.成员 的方式,访问外部类中同名的信息
                       5.外部类访问内部类信息,需要通过内部类实例,无法直接访问
                       6.内部类编译后.class文件命名:外部类$内部类.class
            静态内部类
                static class 内部类名{}
                1.静态内部类对象可以不依赖于外部类对象,直接创建
                2.静态内部类中,只能直接访问外部类的静态成员,如果需要调用外部类的非静态成员,
                   可以通过对象实例
                3.获取静态内部类对象实例:外部类.内部类 对象名=new 外部类().new 内部类()
                4.可以通过 外部类.内部类.静态成员 的方式,访问内部类中的静态成员
                5.当内部类属性与外部类属性同名时,默认直接调用内部类中的成员;如果需要访问外部
                   类中的静态属性,则可以通过 外部类.属性 的方式;
                6.如果需要访问外部类中的非静态属性,则可以通过 new 外部类().属性 的方式;
        方法内部类
            1.定义在方法内部,作用范围也在方法内
            2.和方法内部成员使用规则一样,class前面不可以添加public、private、protected、static
            3.类中不能包含静态成员
            4.类中可以包含final、abstract修饰的成员
            使用时一般将方法设置为Object方法,并return new 内部类名().方法名();
            例如:

面向对象的三大特征_第1张图片
方法内部类

        匿名内部类
            类的定义和创建一起完成
            适用场景:1、只用到类的一个实例
                              2、类在定义后马上用到
                              3、给类命名并不会导致代码更容易被理解
            特点:1.匿名内部类没有类型名称、实例对象名称
                       2.编译后的文件命名:外部类$数字.class
                       3.无法使用private、public、protected,abstract、static修饰
                       4.无法编写构造方法,可以添加构造代码块
                       5.不能出现静态成员
                       6.匿名内部类可以实现接口也可以继承父类,但不可兼得
            图解:


面向对象的三大特征_第2张图片
匿名内部类


总结:通过向上、向下转型实现对象类型的转换,在转换之前由instanceof判断是否可以转换,提高
           代码的强壮型。
           当一个类型只限制子类应该有怎样的方法,且不需要准确知道子类如何实现方法时,可以用
           abstract定义抽象类。
           当多个类型有相同的行为能力,使用接口实现,实现接口的类必须实现接口内的方法体。
           内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中其他类的访
           问,更好的实现了信息隐藏。

你可能感兴趣的:(面向对象的三大特征)