走马观花学Java(一)开始学习java

借鉴公众号: tikujie 三太子敖丙 码匠笔记等
从此时此刻开始,对知识的渴望已让我疯狂且执着,我的人生应该由我自己做主,加油小男孩,你该长大了

链接:
tikujie
三太子敖丙
github地址
码匠笔记

第一 学习流程和路线

借鉴的思维导图: 来自三太子敖丙总结的思维导图
思维导图
注意:这里需要安装开发环境jdk idea git maven等等,等我后面有时间在写吧【因为稍后等于永不,所以估计不会写了,所以自己主动找吃的】,然后idea的破解可以问我也可以上网上找破解方法,jdk的下载版本尽量为1.8的版本,太高的和太低的都不是很合适,java8是比较适合大部分人的【个人观点,不足为据】

面向对象(object-oriented 简称:OO)和面向对象编程(object-oriented-programming 简称:OOP)

面向对象面向过程的的区别
1.共同点:面向对象和面向过程都是解决问题的一种思路.

  • 面向过程:是一种过程,或者流水线一样,有明确的计划步骤等级,不能乱,有序进行。[为实现一个梦想,制定了很多的阶段性计划,但是这些阶段性计划之间是有依赖关系的,前者为后者提供基础或结果,后者依赖前者继续向前获取结果,只要中间有一个步骤出问题将导致整个过程崩盘]
  • 面向对象:将数组与函数绑定到一起,对象有属性和行为,将具体的事分配到具体的对象处理,获取最终的结果,不必要了解对象内部如何操作完成的.[面向对象是基于面向过程的](声明:个人理解,假的也是我自己说的,不能代表什么)

2.不同点:

  • 面向过程:根据业务逻辑,从上到下写代码,强调步骤、每一步都是自己亲自去实现的。
  • 面向对象:将数据和和那护士绑定到一起,进行封装。强调的是找若干个对应的不同专业对象,由专业的的对象来完成这整个过程

来自tikujie的解析:
面向过程:

优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源。
缺点:没有面向对象的优点,不易于维护、复用和扩展
适用场景:

  • 当设计的事物需要高性能时,可以采取这种方式[举个栗子:单片机、Linux/Unix系统等重视的是性能]

面向过程

优点 : 易维护、易复用、易扩展,由于面向对象有封装继承多态,可以将系统设计成低耦合,促使系统更加的灵活,更加易于维护
缺点:性能比面向过程低
适用场景:

  • 提取公共的变量,函数等属性或方法,因为这些变量总是按照某种规律重复出现,方法函数也是,传入的参数总是相同类似,则可以提取这些东西,写作一个模板使用
  • 当某一些属性和方法重复出现,将其封装成一个类也就是模板,用于业务频繁的使用

3.借鉴【拓展

  • 面向对象:
    定义:按人们认识的客观世界的系统思维方式,采用基于对象(实体类)的概念建立模型,模拟客观世界的世界分析、设计、实现软件的办法。可以实现代码的复用,减少代码量。
  • 面向对象编程
    定义:是一种解决软件复用的设计和编程方法。这种方法把软件系统中相近相似的操作逻辑和操作,以及应用数据和状态的方式和实现软件的方法抽取出来。实现了代码的复用,减少了代码量。
  • 类似的词(再次解释,我愿意)
    简写字母对应的含义:
    面向对象(object-oriented 简称:OO):面向对象将功能等通过对象来实现,将功能封装近对象之中,让对象实现具体的细节,需要什么功能直接使用就行了,不用一步一步去实现,至于这个功能怎么实现的,不需要关心,只要会用就行了,等于是站在了巨人的肩膀上面向对象将面向过程的执行者变成了指挥者,只需要关注需求就可。而面向过程不但要关注需求,还需要关注具体的实现细节,需要自己亲力亲为。每一个步骤都不能缺失,失去某一步也无法达到目标。对应实际开发中,面向过程是具体化的,流程化的,解决任何一个问题,需要自己一步一步的分析和一步一步的实现

面向对象:

  • 将复杂的事情简化
  • 松耦合,易维护(对象可以复用和替换)
    -高扩展性(多态)

面向过程

  • 性能比面向对象好,类调用时需要实例化,资源损耗大
  • 面向对象的底层是面向过程的算法和逻辑来实现的,面向对象和面向过程相互依存,不是对立的,只是两种实现方式,恰巧面向对象比较适宜大量的用户需要和心理需要

面向对象分析(object-oriented-analysis 简称:OOA):建模,对客观存在的事物建立理论模型。
面向对象设计(object-oriented-design 简称:OOD):把分析阶段得到的需求抽象为系统实现方案的过程。
面向对象编程(object-oriented-programming 简称:OOP):将设计好的系统通过代码编程实现

  • 面向对象的特征
    1.对象的唯一性:首先需要明白什么是对象,对象或者类其实就是对一类事务的总结,获取其共同的属性和行为。这就另类的表明了每一个对象其自身是唯一的,不同的对象不能有相同的属性和行为【如果真的出现这种情况:思考一下为什么不用统一个对象表示?为什么没有合并,阻止其不能合并的因素就是对象的特殊属性和行为,就可以作为其的唯一性的标识】
    2.抽象性:【定义】是指将某一类事务具有一致的数据类型(属性)和行为(方法)抽象成类,这个类反映了与应用有关的重要性质,而忽略一些无关属性(这是一种主观行为,一百个读者一百个哈姆雷特)
    这里声明一下我学的java】Java是单继承多实现但是在接口中可以多继承

4.面向对象的特性[封装继承多态抽象]

  • 封装

tikujie 中解释:通常认为封装是将数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口【面向对象的本质就是将现实世界描绘成一系列完全自治、封闭的对象】 我们在类中编写的方法就是对实现的细节的一种封装,而封装就是隐藏一些可以隐藏的东西,只向外界提供简单的接口。用户只需要会使用,不需要理解其内部算法和逻辑。

  • 继承

菜鸟教程讲解到:继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
沙滩de流沙中讲解到:

  • Sun的Java Tutorial中是这么说的:

A subclass inherits all the member variables and methods from its superclass.However, the subclass might not have access to an inherited member variable or method.For example, a subclass cannot access a private member inherited from its superclass.One might think,then,that the item was not inherited at all.But the item is inherited.This becomes important when using an inner class,which does have access to its enclosing class’s private members.Note that constructors are not members and so are not inherited by subclasses.
以上这句话的意思:
子类继承了其父类的所有成员变量和方法。但是,子类可能无法访问继承的成员变量或方法。例如,子类无法访问从其父类继承的私有成员。表示该项目根本没有被继承。但是该项目是被继承的。当使用内部类时,这一点很重要,该内部类可以访问其所在类的私有成员。请注意,构造函数不是成员,因此不会被子类继承
重点: 父类中的private属性,子类是可以继承的,但是不能直接使用,需要通过父类提供的外部方法去改变属性

  • 多态
    个人理解:多态因为不同的实例对象去调用相同的接口,而执行了不同的操作和表现形式。

tikujie 中解释:多态是指允许不同子类型的对象对同意消息做出不同的响应。简单的说就是用不同的对象引用调用同样的方法,做了不同的事情。多态性分为编译时的多态性和运行时的多态性。
方法重载(overload):实现的是编译时的多态性(前绑定)。
方法重写(override):实现的是运行时的多态性(后绑定)。

crane_practice写的关于多态的文章是我个人觉得很详细的文章,展示作为借鉴,就不做过多画蛇添足的总结。好的知识点借鉴:
子类型(subType)和子类(subClass)

子类(subClass): 只要是A类运用了extends关键字实现了对B类的继承,那么我们就可以说Class A是Class B的子类,子类是一个语法层面上的词,只要满足继承的语法,就存在子类关系。
子类型(subType): 子类型比子类有更严格的要求,它不仅要求有继承的语法,同时要求 如果存在子类对父类方法的改写(override),那么改写的内容必须符合父类原本的语义,其被调用后的作用应该和父类实现的效果方向一致

重点:只有保证子类都是子类型,多态才有意义

多态的机制

1.编译时多态(静态多态): 重载(overload)就是编译时多态的一个例子,编译时多态在编译时就已经确定,运行的时候调用的是确定的方法
2.运行时多态(动态多态): 通常所说的多态指的都是运行时多态,也就是编译时不确定究竟调用哪个具体方法,一直延迟到运行时才能确定。 这也是为什么有时候多态方法又被称为延迟方法的原因。
3.主要解析运行时多态(简称:多态):

主要的实现方式有:子类继承父类(extends)、实现类实现接口(implements)
核心: 对父类方法的重写和对接口方法中的实现,以取得在运行时不同类型对象的执行效果不同。
法则1: 要使用多态,就应该遵循一条这样的法则:声明的总是父类类型或接口类型,创建的却是实际类型。
正确的示例:List<类型对象> list = new ArrayList<>();
反例:ArrayList<类型对象> list = new ArrayList<>();
法则2: 在定义方法参数时也通常总是应该优先使用父类类型或接口类型。
正确的示例:public void methodA(List<类型对象> list)
反例:public void methodA(ArrayList<类型对象> list)
遵循上面法则的好处:在于结构的灵活性:假如某一天我认为ArrayList的特性无法满足我的要求,我希望能够用LinkedList来代替它,那么只需要在对象创建的地方把new ArrayList()改为new LinkedList即可,其它代码一概不用改动
实现的方式:虚拟机会在执行程序时动态调用实际类的方法,它会通过一种名为动态绑定(又称延迟绑定)的机制自动实现,这个过程对程序员来说是透明的

多态的用途:

  • 对设计和架构的复用:针对接口编程而不是针对实现编程就是充分利用多态。
  • 定义功能和组件时定义接口,实现可以留到之后的流程中
    多态的实现:(从虚拟机运行时的角度来简要介绍多态的实现原理)
    在JVM执行Java字节码时,类型信息被存放在方法区中,通常为了优化对象调用方法的速度,方法区的类型信息中增加一个指针,该指针指向一张记录该类方法入口的表(称为方法表),表中的每一项都是指向相应方法的指针。
    方法表的构造如下:
    由于Java的单继承机制,一个类只能继承一个父类,而所有的类又都继承自Object类。方法表中最先存放的是Object类的方法,接下来是该类的父类的方法,最后是该类本身的方法。这里关键的地方在于,如果子类改写了父类的方法,那么子类和父类的那些同名方法共享一个方法表项,都被认作是父类的方法
    注意这里只有非私有的实例方法才会出现并且静态方法也不会出现在这里,原因很容易理解:静态方法跟对象无关,可以将方法地址直接引用,而不像实例方法需要间接引用。
    更深入地讲,静态方法是由虚拟机指令invokestatic调用的,私有方法和构造函数则是由invokespecial指令调用,只有被invokevirtual和invokeinterface指令调用的方法才会在方法表中出现。
    由于以上方法的排列特性 (Object——父类——子类),使得 方法表的偏移量总是固定的。例如,对于任何类来说,其方法表中equals方法的偏移量总是一个定值,所有继承某父类的子类的方法表中,其父类所定义的方法的偏移量也总是一个定值。
    前面说过,方法表中的表项都是指向该类对应方法的指针,这里就开始了多态的实现:
    假设Class A是Class B的子类,并且A改写了B的方法method(),那么在B的方法表中,method方法的指针指向的就是B的method方法入口。
    而对于A来说,它的方法表中的method方法则会指向其自身的method方法而非其父类的(这在类加载器载入该类时已经保证,同时JVM会保证总是能从对象引用指向正确的类型信息)。
    结合方法指针偏移量是固定的以及指针总是指向实际类的方法域,我们不难发现多态的机制就在这里
    在调用方法时,实际上必须首先完成实例方法的符号引用解析,结果是该符号引用被解析为方法表的偏移量。虚拟机通过对象引用得到方法区中类型信息的入口,查询类的方法表,当将子类对象声明为父类类型时,形式上调用的是父类方法,此时虚拟机会从实际类的方法表(虽然声明的是父类,但是实际上这里的类型信息中存放的是子类的信息)中查找该方法名对应的指针(这里用“查找”实际上是不合适的,前面提到过,方法的偏移量是固定的,所以只需根据偏移量就能获得指针),进而就能指向实际类的方法了。
    我们的故事还没有结束,事实上上面的过程仅仅是利用继承实现多态的内部机制,多态的另外一种实现方式:实现接口相比而言就更加复杂,原因在于,Java的单继承保证了类的线性关系而接口可以同时实现多个,这样光凭偏移量就很难准确获得方法的指针。所以在JVM中,多态的实例方法调用实际上有两种指令:
    invokevirtual指令用于调用声明为类的方法;
    invokeinterface指令用于调用声明为接口的方法。
    当使用invokeinterface指令调用方法时,就不能采用固定偏移量的办法,只能老老实实挨个找了(当然实际实现并不一定如此,JVM规范并没有规定究竟如何实现这种查找,不同的JVM实现可以有不同的优化算法来提高搜索效率)。我们不难看出,在性能上,调用接口引用的方法通常总是比调用类的引用的方法要慢。这也告诉我们,在类和接口之间优先选择接口作为设计并不总是正确的,当然设计问题不在本文探讨的范围之内,但显然具体问题具体分析仍然不失为更好的选择。

作者的个人见解:动态多态是在编译时不能确定调用哪个方法,得在运行时确定。动态多态的实现方法包括子类继承父类和类实现接口。当多个子类上转型(不知道这么说对不)时,对象掉用的是相应子类的方法,这种实现是与JVM有关的。

借鉴完成
借鉴地址再次声明:https://www.cnblogs.com/crane-practice/p/3671074.html

拓展

留下后续补充的空间…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值