Java教程

Java-面向对象OOP详解

本文主要是介绍Java-面向对象OOP详解,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

一、初识面向对象

  • 面向过程思想

    步骤简单

    处理简单的问题

  • 面向对象思想

    物以类聚、分类的思维方式

    适合处理复杂的问题

    适合处理需要多人协作的问题

对于描述复杂的事物,需要从宏观上把握、从整体上合理分析——使用面向对象的思路来分析整个系统

具体到微观操作,仍然需要面向过程的思路去处理

二、什么是面向对象

  • 面向对象编程

    Object-Oriented Programming——OOP

  • 面向对象编程的本质

    以类的方式组织代码、以对象的方式组织/封装数据

  • 抽象

  • 三大特性

    • 封装
    • 继承
    • 多态
  • 认识论角度——先有对象、后有类

    对象是具体的事物

    类是对 对象的抽象

  • 代码运行角度——先有类、后有对象

    类是对象的模板

    对象是对类的一个实例化

面向过程比较直接高效,而面向对象更易于复用、扩展和维护

三、方法的调用

  • 静态方法

  • 非静态方法

  • 形参与实参

  • 值传递

  • 引用传递

  • this关键字 指向本类

四、类、对象的创建与使用

  • 类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物
  • 对象是抽象概念的具体实例

五、创建和初始化对象

  • 使用new关键字创建对象
    • 使用new关键字创建时,除了要分配内存空间以外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用
    • 类中构造器也称构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下特点:
      • 必须和类的名字相同
      • 必须没有返回类型,也不能写void
    • 构造器必须要掌握
      • Alt + Insert 快捷键 生成构造方法 Getter Setter方法等
      • 作用
          1. new 本质在调用构造方法
          2. 初始化对象的值
      • 注意点
          1. 定义有参构造之后,如果想要使用无参构造,必须显示的定义一个无参构造

六、创建对象内存分析

七、封装

高内聚、低耦合

内部数据操作细节由自己完成,不允许外部干涉

仅暴露少量的方法给外部使用

属性私有 get/set

禁止直接访问一个对象中的数据的实际表示

八、继承

本质:对某一批类的抽象,从而实现对现实世界更好的建模

extends 扩展 子类是父类的扩展

Java类中只有单继承 没有多继承!

继承是类和类之间的一种关系,除此之外,类和类之间的关系还有依赖、组合、聚合等

继承关系的两个类,一个为子类(派生类),一个为父类(基类)。

子类继承父类,使用关键字 extends 来表示

子类和父类之间,从意义上来讲应该具有 “is a ”的关系

  • object 类 所有类默认直接/间接继承Object类

  • super()

    • super注意点
      • super调用父类的构造方法,必须在构造方法的第一个
      • super必须只能出现在子类的方法或者构造器/构造方法中
      • super和this不能同时调用构造方法
  • this() 调用本类

    和super代表的对象不同

    • this : 本身调用者这个对象
    • super :代表父类对象的应用

    前提:

    • this - 没有继承也能使用
    • super - 在继承条件下才能使用

    构造方法:

    • this() :本类的构造
    • super():父类的构造
  • 方法重写

    • 重写需要有继承关系

      ​ 子类重写父类的方法!

      1. 方法名必须相同

      2. 参数列表必须相同

      3. (子类)修饰符可以扩大,但是不能缩小

        public > protected > default > private

      4. 抛出的异常:范围=>可以被缩小 但不能被扩大

    • 重写时 子类的方法和父类必须一致;方法体不同

  • 为什么需要重写?

    • 父类的功能,子类不一定需要或不一定满足
    • ALT + insert : Override 重写

九、多态

  • 定义

    • 即同一方法可以根据发送对象的不同而采用多种不同的行为方式
  • 一个对象的实际类型是确定的,但可以指向对象的引用类型有很多(父类/有关系的类)

  • 多态存在的条件:

    • 有继承关系

    • 子类重写父类的方法

    • 父类的引用指向子类的对象

      Father f1 = new Son();

  • 注意:

      1. 多态是方法的多态,属性没有多态性
      1. 父类和子类有联系 类型转换异常@ClasscastException
  • 方法不需要重写的情况:

    • static 方法,属于类,不属于实例
    • finnal 方法 常量
    • private 方法,无权限
  • instanceof & 类型转换 - 引用类型之间的转换

    • 判断两个 类实例/对象 之间是否可以进行类型转换
    • 输出结果类型为 boolean
    • A instanceof B
      • 若A、B不存在线性父子关系/A、B不在同一条原型链上,则会编译报错
      • 若正常通过编译,进行A、之间的比较,则会得到一个Boolean类型的结果
        • True: A 是 B本类或者子类的对象
        • False: A 不是 B 本类或子类的对象
  • 父类调用子类独有的方法时,需要向下转型/强制转换,

  • 父类引用指向子类的对象

  • 子类转换为父类 => 向上转型 / 自动转换 !但是可能丢失自己本来已有的方法

  • 父类转换为子类 => 向下转型 / 强制转换,可能会损失精度

十一、抽象类

  • abstract 修饰符
    • 用来修饰方法 => 抽象方法
    • 用来修饰类 => 抽象类
  • 抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类
  • 抽象类 不能 使用 new 关键字来创建对象,它是用来让子类继承的
  • 抽象方法 只有方法的声明。没有方法的实现,它是用来让子类实现的
  • 子类继承抽象类 必须要实现抽象类中只有声明却没有实现的抽象方法,否则该子类也要声明为抽象类。

十二、接口

  • 普通类:只有具体实现

  • 抽象类: 具体实现和规范(抽象方法)都有!

  • 接口:只有规范! 自己无法写方法 ,专业的约束!

    约束和实现分离 => 面向接口编程

  • 接口就是规范

    定义的是一组规则,体现了现实世界中“如果你是...,则必须能...”的思想

    e.g. 如果你是汽车,你必须能跑...

  • 接口的本质是契约,制定好之后大家都必须遵守

  • OOP的精髓:对于 对象的抽象

    最能体现这一点的是接口

    为什么我们讨论设计模式都只针对具备了抽象能力的语言

    (C++、java、C#等),就是因为设计模式所研究的,实际上就是如何合理的去抽象。

声明类的关键字 => class

声明接口的关键字 => interface

  • 作用
      1. 约束
      2. 定义一些方法(没有具体实现),让不同的人实现
      3. public abstract 接口中方法的默认修饰符
      4. public static final 接口中属性的默认修饰符
      5. 接口不能被实例化; 接口中没有构造方法
      6. implements 可以实现多个 接口
      7. 必须要重写接口中的方法

十三、内部类

  • 所谓内部类,即是在一个类的内部再定义一个类,比如A类中定义一个B类,那么B类相对A类称为内部类,而A类相对B类来说就是外部类。

    1. 成员内部类 / 非静态内部类

      和静态内部类非常相似,都是定义在一个类中的成员位置,但是没有static修饰

      特点:

      • 虽然是定义在类的内部,但是内部类和外部类并不是继承关系

      • 成员内部类定义在外部类的成员位置上

      • 会生成两个.class文件,一个是Outer.class,一个是Inner.class。

      • 生成成员内部类的实例对象的语法: Outer.Inner inner = new Outer().Inner();

        inner.method();

    2. 静态内部类

      使用static修饰的内部类

      public class Outer{
          static class Inner{
              // 静态内部类
          }
      }
      

      特点:

      • 在创建静态内部类的实例时,不需要创建外部类的实例!
      • 静态内部类中可以定义静态成员和实例成员
      • 静态内部类可以直接访问外部类的静态成员,如果要访问外部类的成员变量,则需要创建外部类的实例。
    3. 局部内部类

      局部内部类是指在一个方法中定义的内部类

      public class Test{
          public void method(){
              class Inner{
                  // 局部内部类
              }
          }
      }
      

      特点:

      • 局部内部类与局部变量一样,不能使用访问控制修饰符(public、protected、private)和 static 修饰符 来修饰
      • 局部内部类只在当前方法中有效
      • 局部内部类中不能定义static成员
      • 局部内部类中还可以包含内部类,但是这些内部类都不能使用访问控制修饰符(public、protected、private)和 static 修饰符 来修饰
      • 在局部内部类中可以访问外部类的所有成员
      • 局部内部类中只可以访问当前方法中final类型的参数与变量!如果方法中的成员与外部类中的成员同名,则可以使用.this.的形式访问外部类中的成员。
    4. 匿名内部类 AnonymousInnerClass

      匿名类是指没有类名的内部类,必须在创建时使用new语句来声明类

      new Thread(){
          // 类的主体
      }
      

      作用:对给定的类进行拓展,或者实现一个给定的接口。

      使用匿名类可使代码更加简洁、紧凑,模块化程度更高

      匿名类的两种实现方式:

      • 继承一个类,重写其方法
      • 实现一个接口(也可以是多个),实现其方法

      特点:

      • 和局部内部类一样,可以访问外部类的所有成员

        如果匿名内部类位于一个方法中,则匿名内部类只能访问方法中的final类型的局部变量和参数

        注意:从 Java 8 开始添加了 Effectively final 功能,在 Java 8 及以后的版本中代码第 6 行不会出现编译错误

        Java 中局部内部类和匿名内部类访问的局部变量必须由 final 修饰,以保证内部类和外部类的数据一致性。但从 Java 8 开始,我们可以不加 final 修饰符,由系统默认添加,当然这在 Java 8 以前的版本是不允许的。Java 将这个功能称为 Effectively final 功能。

      • 匿名内部类中允许使用非静态代码块进行成员初始化操作

      • 匿名内部类的非静态代码块会在父类的构造方法之后被执行

这篇关于Java-面向对象OOP详解的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!