Java基础之OOP

Posted sanxiandoupi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java基础之OOP相关的知识,希望对你有一定的参考价值。

什么是面向对象

面向对象: 把问题分解成一个个步骤, 对每个步骤进行抽象, 形成对象, 对象内有数据也有对数据的操作, 然后基于这些对象以及对象的功能进行业务逻辑的实现

面向对象的优点是:易维护, 代码复用, 扩展, 而且由于封装, 继承, 多态的特性, 可以设计出低耦合的系统

缺点是: 性能比面向过程差, 因为存在对象的创建, 销毁等过程, 这样比较消耗资源

面向过程: 是具体化的, 流程化的, 解决一个问题, 就需要一步步的分析, 设计一个个的函数去实现.

优点是性能好, 缺点是维护性差, 并且不容易代码复用和扩展


面向对象的三大特性

  • 封装
    • 隐藏对象的属性和实现细节, 只对外提供公共访问方式, 对对象内部的数据提供了不同级别的保护, 提高了代码复用和安全性.
  • 继承
    • 描述类之间的 “is a” 的关系, 是一个从一般到特殊的过程, 子类继承父类数据和方法, 并且可以在无需重复编写代码的情况下扩展功能, 实现了代码复用, 同时继承是多态的前提
  • 多态
    • 程序中定义的引用变量所指向的具体类型在没运行前并不确定, 调用的方法也就无法确定有什么功能. 这个是在运行时才可以确定的. 这样, 不用修改源代码, 就可以让引用变量绑定到各种不同的实现类上, 从而导致方法提供的功能随之改变, 让程序可以有多个运行状态.
    • 同一操作作用于不用的对象, 可以有不同的解释,产生不同的执行结果


面向对象的五大基本原则

1、单一职责原则 类的功能要单一,最好只做一件事, 具有一个职责. 职责可以理解为引起变化的原因, 如果职责过多, 就等于把这些职责耦合在一起了, 一个职责的变化可能会引起其他职责的变化, 单一职责就是要解耦合, 并且增强一个类的内聚性

2、开放封闭原则OCP(Open-Close Principle) 一个模块对于扩展是开放的,对于修改是封闭的. 核心思想是对抽象编程, 而不对具体编程, 因为抽象相对稳定. 让类依赖于固定的抽象, 所以修改就是封闭的; 而通过面向对象的继承和多态机制, 又可以实现对抽象的继承实现, 通过重写方法来改变固有行为, 实现新的扩展方法, 所以是开放的


3、里式替换原则 子类可以替换父类, 同时程序的行为不会发生任何变化


4、依赖倒置原则DIP(the Dependency Inversion Principle DIP) 高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。抽象不应该依赖于具体实现,具体实现应该依赖于抽象。

当两个模块之间存在紧密的耦合关系时, 最好的方法就是分离接口和实现, 在依赖之间定义一个抽象的接口, 让高层模块调用接口, 底层模块实现接口的定义, 通过这种方式来控制耦合关系, 达到依赖于抽象的设计目标

抽象的稳定性决定了系统的稳定性,因为抽象是不变的,依赖于抽象是面向对象设计的精髓,也是依赖倒置原则的核心。


5、接口分离原则 使用多个小的专门的接口,而不要使用一个大的总接口。

大的接口有明显的弊端, 它会导致实现的类必须完全实现接口的所有方法, 而实现类并非需要所有的方法. 而且如果对大的接口进行修改, 就会影响所有的实现类.

分类的方式有两种:

  1. 委托分离, 通过增加一个新的类型来委托客户的请求, 隔离客户和接口的直接依赖
  2. 通过接口的多继承来实现客户的需求


Java如何实现平台无关的

对于不同的os和硬件, 最主要的区别就是指令集不同, 而 JVM 是平台相关的, 在不同的平台上有不同的实现版本

运行.java文件时, 首先将它编译成.class字节码文件, 这是一种中间代码, 然后交给JVM去解释执行, 到底生成什么样的机器代码是由不同机器上的JVM决定的, 并且不同平台上的 JVM 都遵循同一个规范, 这样就实现了平台无关性.

值传递与引用传递

值传递是复制变量的一个副本, 对形参修改时不会影响到实际参数

引用传递是传递实参的地址, 在函数中对参数进行的修改会影响到实际参数

至于为什么说Java中只有值传递, 是因为传递引用就是传递对象地址, 是复制对象引用的地址复制了一份, 再传递给了形参


方法的重载与重写

Human man = new Man(); Human是静态类型, Man 是动态类型

程序在JVM运行过程中,会把类的类型信息、static属性和方法、final常量等元数据加载到方法区,这些在类被加载时就已经知道,不需对象的创建就能访问的,就是静态绑定的内容;需要等对象创建出来,使用时根据堆中的实例对象的类型才进行取用的就是动态绑定的内容。

方法区又称为永久代, 存放虚拟机加载的类信息, final常量, static常量, 方法, 即时编译后的代码等数据. 方法区的回收目标主要是对常量池的回收以及类的卸载, 当内存空间不足时, 无法为方法区开辟新的内存空间时, 会抛出OutOfMemoryError, 运行时常量池, 存储类加载后的常量池信息

首先, 重载是针对同一个类中的方法, 也是多态性的一个体现, 方法名相同, 但是参数列表不同, 这样就可以根据传入的参数不同而表现出不同的行为; 而重写是针对类的继承, 子类继承父类, 重写父类方法 (方法要求有相同的方法名, 参数列表, 返回值类型), 新方法覆盖原有的方法, 如果要访问父类方法, 可以通过super关键字访问, super引用的当前类的父类, 同时子类方法的访问权限不能小于父类.

Java 中的重载是由静态类型确定的, 在类加载的时候就可以确定, 属于静态分派;

重写是由动态类型确定, 并且运行时确定, 属于动态分派. 动态分派由虚方法表实现, 虚方法表中存放着各个方法的实际入口地址, 如果父类中的某个方法子类没有被重写, 则父类与子类的方法表中的方法地址相同. 如果重写了, 子类方法表中的地址指向重写后的方法地址

原文:大专栏  Java基础之OOP


以上是关于Java基础之OOP的主要内容,如果未能解决你的问题,请参考以下文章

java golang oop 2文章片段

Java语言基础之方法的设计

Web基础之Spring AOP与事务

Java基础学习 -- Java(OOP)程序的设计原则

Java基础之方法的调用重载以及简单的递归

java第五章:面向对象(oop)三大特性之多态