本篇博客主要记录Java中面向对象的概念和Java语法的基础知识。

面向对象

什么是面向对象

面向对象是一种优秀的软件设计思想,是相对于面向过程、面向切面等设计思想的一种软件设计理念。它的核心思想是运用更加贴近人类思维的方式去设计软件,将软件中的各个组件抽象成相应的类,再将这些类组装成我们所需的软件系统。

这里举个例子:假如用面向对象的方式设计一个电脑,我们会设计CPU类、硬盘类、显示器类、内存类等等,然后将这些类组合在一起设计成Computer类。

而面向过程的思想在解决问题时会将问题分解成一个个小的函数,然后按照某种顺序去执行这些方法,当这些方法执行完毕,问题也就解决了。

三大基本特征和五项基本原则

面向对象的三大基本特征是:封装、继承和多态。正是基于这些特征,面向对象的开发语言才能拥有更好的可重用性、扩展性和维护性

  • 封装:将对象的实现细节隐藏起来,然后通过一些公共的方法向外部提供该对象的功能;
  • 继承:继承是软件复用的一种重要手段,子类继承父类之后将直接获得父类的属性和方法;
  • 多态:对象可以赋给父类对象或者它实现的接口,但是运行时依然表现出子类或实现类的特征。

面向对象的五大原则如下:

  • 单一职责原则(SRP):一个类专注于实现一个功能;
  • 开闭原则(OCP):对象或实体应该对扩展开放,对修改封闭;
  • 里氏替换原则(LSP):子类可以替换父类并且出现在父类能够出现的任何地方(这个原则就需要我们面向接口编程);
  • 依赖倒置原则(DIP):高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象,抽象不应该依赖于具体实现,具体实现应该依赖于抽象;
  • 接口隔离原则(ISP):使用多个专门的接口比使用单个接口要好的多:在实际编程中,为了减少接口的定义,将许多方法都放在一个接口中,最后发现,维护和实现接口的时候会花费很多精力,接口所定义的操作相当于对客户端的一种承诺,这种承诺当然是越少越好,越精练越好,过多的承诺带来的就是你的大量精力和时间去维护。不要把不相干的方法放在一个接口中定义。

另外还有迪米特原则合成服用原则,也需要我们在设计系统和接口时考虑到。

迪米特法则:又叫最少知识法则,这个法则主张一个类要尽可能少地知道其他类地细节,并且尽可能少地和其他类进行通信交互,只和于自己有密切关系地类进行交互。

合成服用原则:合成服用原则又称为组合/聚合服用原则(Composite/Aggregate Reuse Principle):尽量采用组合(contains-a)、聚合(has-a)的方式而不是继承(is-a)的关系来达到软件的复用目的。

合成服用原则最主要地原因是继承会破环封装:基类的很多内部细节都是对派生类可见的,而有些细节可能是不想让子类知道的。关于继承、组合还有聚合的概念可能比较容易搞混,这边也提下。

继承:子类拥有父类的某些属性和方法,子类可以替换父类;

组合:是整体与部分的关系,整体离不开部分,部分离开了整体没有意义,如飞机翅膀与飞机的关系;

聚合:也是整体与部分的关系,但整体可以分离部分,部分也可以离开整体,如火车与车厢的关系,还有就是聚合支付的列子等。

重载和重写的区别

重载:是指在一个类里面存在多个方法名相同,但是方法参数不同的方法。

重写:是指子类在继承父类时,重新改写了父类的某个方法。子类中的这个方法的方法名和方法参数和父类中的完全一样。

Java基础语法

Java语言是最流行的编程语言,从刚“出生”,Java语言就号称“一次编译,到处运行”。

Java语言能跨平台的关键是JVM能跨平台,JVM屏蔽了操作系统的底层差异,让字节码文件在每个平台上都可以执行。

除了Java,JVM还支持的语言有Kotlin、Groovy、JRuby、Jython、Scala等。另外,随着Oracle对Graal虚拟机的研发,JVM平台将会支持所有的语言,包括JS和C++等语言。

进行Java开发的第一步是下载一个合适版本的JDK,然后配置JAVA_HOME这个环境变量。但是如果你只是需要运行Java程序,那你只需要安装一个JRE即可。JDK和JRE的关系如下:

JDK包含:Java编译器、JRE以及常用的Java类库;

JRE包含:JVM、类加载器、字节码校验器以及核心类库等。

然后就是编译执行Java程序

# -d后面的参数指定生成的字节码文件的生产路径,默认当前目录;
javac -d destDir HelloWorld.java;
# 执行Java程序;
# classpath的作用是提供了一系列路径让Java程序去在这些路径下寻找类,找不到就报错。在Windows上用;号分割,在Linux上用:号分隔
java -classpath %CLAss_PATH%;.;dir1;dir2 HelloWorld;

三种基本的程序结构

  • 顺序结构
  • 选择结构
  • 循环结构

使用这三种结构能编写出任意功能的程序。

Java中的注释

  • 单行注释://
  • 多行注释:/**/
  • 文档注释:/** */ 使用javadoc可以生成api文档

Java中的关键字

Java中一共有48个关键字,2个保留字和三个直接量

  • 访问控制:private、protected、public;
  • 类,方法和变量修饰符:abstract、class、extends、final、implements、interface、native、new、static、strictfp、synchronized、transient、volatile;
  • 程序控制:break、continue、return、do、while、if、else、for、instanceof、switch、case、default;
  • 错误处理:try、cathc、throw、throws、finally;
  • 包相关:import、package;
  • 基本类型:boolean、byte、char、double、float、int、long、short、null、true、false;
  • 变量引用:super、this、void;
  • 保留字:goto、const;
  • 直接量:true、false、null。

重要关键字说明:

  • native: 用来声明一个方法是由与机器相关的语言(如C/C++/FORTRAN语言)实现的;
  • strictfp:用来声明FP-strict(双精度或单精度浮点数)表达式;
  • transient:声明不用序列化的属性;
  • volatile:表明两个或多个变量必须同步地发生变化。

数据类型

Java中的数据类型分为基本数据类型和引用数据类型。

1. 取值范围

8种基本数字类型从大类上分的话分别是布尔型,字符型,整形和浮点型,对应bool,byte,char,short,int,long,float和double类型。

  • byte:一个字节,8个bit位,-2^7 ~ 2^7-1
  • char : 2个字节,16个bit位,0 ~ 2^16-1 ;
  • short:2个字节,16个bit位,-2^15 ~ 2^15-1
  • int:4个字节,32个bit位,-2^31 ~ 2^31-1
  • long:8个字节,64个bit位,-2^63 ~ 2^63-1
  • float:4个字节,32个bit位
  • double:8个字节,64个bit位。

上面的float和double都是浮点类型数据,在计算机中,浮点数用来近似表示任意某个实数。浮点数分为双精度浮点数和单精度浮点数。单精度占4个字节,双精度占8个字节,表示的范围更大。

对于double和float类型的数据,正数除以0得到正无穷,负数除以0得到负无穷,0.0除以0达到NaN。但是整数除以0会得到除0异常。

在要求精确计算的场合,不建议使用浮点型数据。因为浮点数计算的结果不是很精确,是近似的结果。这种情况应该使用BigDecimal。这边举个BigDecimal使用的简单列子:

BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(1.1));
BigDecimal bigDecimal2 = new BigDecimal(String.valueOf(2.223));
String str1 = bigDecimal1.add(bigDecimal2).toString();
//减法
bigDecimal1 = new BigDecimal(String.valueOf(2.2));
bigDecimal2 = new BigDecimal(String.valueOf(10.1));
String str2 = bigDecimal1.subtract(bigDecimal2).toString();
//乘法
bigDecimal1 = new BigDecimal(String.valueOf(1.1));
bigDecimal2 = new BigDecimal(String.valueOf(2.234));
String str3 = bigDecimal1.multiply(bigDecimal2).toString();
//除法
bigDecimal1 = new BigDecimal(String.valueOf(4.4));
bigDecimal2 = new BigDecimal(String.valueOf(3));
//除法需要设置精度和四舍五入的方式
String str4 = bigDecimal1.divide(bigDecimal2,3, RoundingMode.HALF_UP).toString();
//结果
System.out.println("加法结果:" + Double.valueOf(str1));
System.out.println("减法结果:" + Double.valueOf(str2));
System.out.println("乘法结果:" + Double.valueOf(str3));
System.out.println("除法结果:" + Double.valueOf(str4));

2. 基本数据类型之间的转换

char---------------|

byte-->short-->int-->long-->float-->double

对于上面的转换关系做下说明:char可以自动转换成int,byte可以自动转换成short,short可以自动转换成int。这些转换过程都是自动完成的。

short a = 3;
int b = a;

那么将int赋值给short,或者将double赋值给int可不可以呢?答案是可以的,但是最后的数据可能不是我们预期的值。因为int占的字节数比short长,short盛放不下,会做数据截取。

  • 整数之间的强制转换:比如int转换为short会缩短位数;
  • double向int转换:会截掉小数部分。

3. 表达式类型自动提升

整个表达式的类型会提升为表达式中最高等级的类型。

short aa = 1;
//这个表达式会报错,aa+2会自动提升为int
short bb = aa+2;

包装类类型

包装类型是相对于基本数据类型来讲的。Java中有8种基本数据类型,每个基本数据类型都有相对的包装类型。比如int的包装类型是Integer。包装类型都是是引用类型,而且都是不可变类。

关于包装类型,有两个概念需要我们了解:

  • 自动装箱:将基本数据类型赋值给包装类型的过程,实现原理是编译器层面new了一个包装类再赋值给相应的变量(如果是是将包装类缓存过的数值赋值给包装类的化,不会new新的包装了,而是直接使用缓存的对象);
  • 自动拆箱:包装类型直接赋值给基本数据类型,实现原理类似,也是编译器层面调用了包装类的getValue方法再赋值给对应的基本数值类型。

比较有趣的是,包装类型在加载的过程中都会缓存某些值的类。比如Integer会缓存-128到127的类。

//不会使用缓存的数据
Integer num1 = new Integer(1);
//会使用缓存的数据,实际上是调用了Integer.valueOf方法
Integer num2 = 1;

通过设置-XX:AutoBoxCacheMax=?这个参数,可以调整Integer缓存的最大值。当然其他包装类型也有类似的行为,Byte、Short和Long都缓存了-128到127的类,Character缓存了0到127的类,但是这些类不能像Integer那样修改缓存的最大值。

关于基本数据类型和包装类型的使用,介绍一个阿里巴巴开发规范中的原则:

所有的POJO类属性必须使用包装数据类型;RPC方法的返回值和参数必须使用包装类型;所有的局部变量尽量使用基本数据类型。

定义布尔型的类变量,变量名不要以is打头。

Java中的值传递和引用传递

基本数据类型,保存的是数据本身的值,按值传递;引用类型的变量保存的是对象在内存中的地址,按引用传递(引用传递可以看成是一种特殊的值传递)。

一个问题

Java中的bool变量到底占用多大的内存呢?网上的各种说法都有?欢迎大家留言讨论。

公众号推荐

欢迎大家关注我的微信公众号「程序员自由之路」

你不得不知的Java基础知识的更多相关文章

  1. 沉淀,再出发:Java基础知识汇总

    沉淀,再出发:Java基础知识汇总 一.前言 不管走得多远,基础知识是最重要的,这些知识就是建造一座座高楼大厦的基石和钢筋水泥.对于Java这门包含了编程方方面面的语言,有着太多的基础知识了,从最初的 ...

  2. 生活点滴:java基础知识细化

    生活点滴:java基础知识细化 一.前言 越是对一门语言深入了解,就会发现自己不知道的东西越多,这才是走向了正道,同样的,对于java语言特性的学习,笔者也只是初窥门径. 二.java基础知识思考 i ...

  3. Java基础知识(壹)

    写在前面的话 这篇博客,是很早之前自己的学习Java基础知识的,所记录的内容,仅仅是当时学习的一个总结随笔.现在分享出来,希望能帮助大家,如有不足的,希望大家支出. 后续会继续分享基础知识手记.希望能 ...

  4. java基础知识小总结【转】

    java基础知识小总结 在一个独立的原始程序里,只能有一个 public 类,却可以有许多 non-public 类.此外,若是在一个 Java 程序中没有一个类是 public,那么该 Java 程 ...

  5. Java基础知识系列——String

    最近晚上没有什么事(主要是不加班有单身),就复习了一下Java的基础知识.我复习Java基础知识主要是依据Java API和The Java™ Tutorials. 今天是第一篇,复习了一下Strin ...

  6. 学习android学习必备的java基础知识--四大内部类

    学习android必备的java基础知识--四大内部类 今天学习android课程,因为我的主专业是JAVA,但是兴趣班却有这其他专业的同学,学习android 需要具备一些java的基础知识,因此就 ...

  7. JAVA基础知识之网络编程——-网络基础(Java的http get和post请求,多线程下载)

    本文主要介绍java.net下为网络编程提供的一些基础包,InetAddress代表一个IP协议对象,可以用来获取IP地址,Host name之类的信息.URL和URLConnect可以用来访问web ...

  8. java基础知识梳理

    java基础知识梳理 1 基本数据类型

  9. java基础知识回顾之---java String final类普通方法

    辞职了,最近一段时间在找工作,把在大二的时候学习java基础知识回顾下,拿出来跟大家分享,如果有问题,欢迎大家的指正. /*     * 按照面向对象的思想对字符串进行功能分类.     *      ...

随机推荐

  1. myBatis源码解析-数据源篇(3)

    前言:我们使用mybatis时,关于数据源的配置多使用如c3p0,druid等第三方的数据源.其实mybatis内置了数据源的实现,提供了连接数据库,池的功能.在分析了缓存和日志包的源码后,接下来分析 ...

  2. Java查表法实现十进制转化成其它进制

    首先了解十进制转化成二级制的原理 156的二进制为: 156 % 2 = 78 …… 0 83 % 2 = 39 …… 0 39 % 2 = 19 …… 1 19 % 2 = 9 …… 1 9 % 2 ...

  3. Java进阶知识

    01[Object类.常用API] 主要内容 Object类 Date类 DateFormat类 Calendar类 System类 StringBuilder类 包装类 第一章 Object类 1. ...

  4. 我搭的神经网络不work该怎么办!看看这11条新手最容易犯的错误

    1. 忘了数据规范化 2. 没有检查结果 3. 忘了数据预处理 4. 忘了正则化 5. 设置了过大的批次大小 6. 使用了不适当的学习率 7. 在最后一层使用了错误的激活函数 8. 网络含有不良梯度 ...

  5. JavaScript Number() 函数

    JavaScript Number() 函数 JavaScript 全局对象 定义和用法 Number() 函数把对象的值转换为数字. 语法 Number(object) 参数 描述 object 必 ...

  6. C#LeetCode刷题-分治算法

    分治算法篇 # 题名 刷题 通过率 难度 4 两个排序数组的中位数 C#LeetCode刷题之#4-两个排序数组的中位数(Median of Two Sorted Arrays)-该题未达最优解 30 ...

  7. Java中访问控制修饰符的详解和示例——Java学习

    Java中的四个访问控制修饰符 简述 在Java中共有四个: public -- 对外部完全可见 protected -- 对本包和所有子类可见 默认(不需要修饰符)-- 对本包可见 private ...

  8. 用WindowsAPI实现文件复制功能

    用WindowsAPI实现文件复制功能 1. c代码 注释也在里面 文件名为 copyfile.c 运行出来的exe为 copyfile.exe #include <windows.h> ...

  9. YAML简要入门

    这是一篇简单的YAML入门教程,目的是让你知晓什么YAML,以及YAML的基础语法.方便接下来学习如何使用Golang解析YAML.如果想获得更多YAML的知识,请查看http://yaml.org ...

  10. Android java.lang.SecurityException: Permission Denial

    报错: java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE ...