JAVA学习笔记二

◇◆丶佛笑我妖孽 提交于 2020-02-14 01:16:53

JAVA学习笔记二

五、继承、接口和抽象类

继承extends

父类/基类/超类
parent/base/super
子类/派生类
child/derived

子类不可访问父类private成员
同名方法优先调用子类

单根继承(区别于C++):每个类只能继承一个类
默认继承java.lang.Object(所有类构成类型继承树),Object类默认有clone,equals,finalize,getClass,hashCode,toString等方法

默认super(),只有一个super(),调用父类的构造函数

抽象类和接口

类:属性(0或多个)+方法(0或多个)
一个完整的类:所有的方法都有实现(方法体)
抽象类:暂时有方法未实现

抽象类组成(类名前加abstract class):

  • (optional)成员变量
  • (optional)具体方法,方法有实现
  • (optional)抽象方法,加abstract关键字

子类必须实现父类抽象类所有的abstract方法才能成为完整类!

接口类interface:所有方法均未实现
P.s.方法不需要加abstract

一个类只可以继承(extends)一个类,但是可以实现(implements)多个接口,继承和实现可以同时。
P.s.弥补单根继承的不足

接口可以继承多个接口,没有实现的方法将会叠加。
没有全部实现方法,就是抽象类。
接口里可以定义变量,一般为常量(final)。

P.s.先extends后implements

抽象类和接口相同点:

  • 两者都不能被实例化,不能new操作
    P.s.抽象类可new,但是new时需要补全,只可以使用一次

抽象类和接口不同点:

  • 抽象类可以有部分方法实现,接口所有方法不能有实现
  • 一个类只能继承(extends)一个(抽象)类,实现(implements)多个接口
  • 接口可以继承(extends)多个接口
  • 抽象类有构造函数,接口没有构造函数
  • 抽象类可以有main,也能运行,接口没有main函数
  • 抽象类方法可以有private/protected, 接口方法都是public

转型、多态和契约设计

类转型

1.变量支持互相转化
2.子类可以转换成父类(向上转型),而父类不可以转换为子类(向下转型)
E.g.

Human obj1=new Man();
Man obj2=new Human(); //illegal,Man is a derived class Human

父类转为子类有一种情况例外
-就是父类本身就是从子类转化过来的。

E.g.

Human obj1=new Man();
Man obj2=(Man)obj1;
多态

重写(overwrite/override,not overload!):子类继承父类的所有方法,但子类可以重新定义一个名字、参数和父类一样的方法
P.s.overload重载:形参不同
P.s.子类的方法的优先级高于父类。子类转换父类后,会优先调用子类的方法(理解为被掩盖却依旧存在)!

多态的作用:

  • 以统一的接口来操纵某一类中不同的对象的动态行为
  • 对象之间的解耦

E.g.父类[i]=子类实例0
父类[i].f()==子类.f()

契约设计

契约:规定规范对象应该包含的行为方法
接口定义了方法的名称、参数和返回值,规范了派生类的行为
基于接口,利用转型和多态,不影响真正方法的调用,成功地将调用类和被调用类解耦(decoupling)

契约设计:类不会直接使用另外一个类,而是采用接口的形式,外部可以“空投”这个接口下的任意子类对象

六、static、final和常量设计

static

变量 方法 类 匿名代码块

静态变量,类公有成员?
依赖类存在,不依赖类实例存在
P.s.可用类.静态变量访问

static方法

  • 静态方法也无需通过对象来引用,而通过类名可以直
    接引用。
  • 在静态方法中,只能使用静态变量,不能使用非静态
    变量。
  • 静态方法禁止引用非静态方法。

P.s.main前加static原因
用static修饰的方法,无须产生类的实例对象就可以调用该方法。

static块

  • 只在类第一次被加载时调用,只运行一次。
  • 执行顺序:static块 > 匿名块 > 构造函数。

static{

}
{

}

单例模式(单态模式)singleton

单例模式:保证一个类有且只有一个对象

  • 采用static 来共享对象实例
  • 采用private 构造函数,防止外界new操作

final

Java的final关键字同样可以用来修饰 类、方法、字段

  • final的类,不能被继承
  • 父类中如果有final的方法,子类中不能改写此方法

final的变量,不能再次赋值。

  • 如果是基本型别的变量,不能修改其值
  • 如果是对象实例,那么不能修改其指针(但是可以修改对象内部的值)

常量设计和常量池

常量设计

与C/C++不同,Java无constant关键字
public static final

  • 不能修改,final
  • 不会修改/只读/只要一份,static
  • 方便访问public

P.s.建议变量名字全大写,以连字符相连,如UPPER_BOUND
一种特殊的常量:接口内定义的变量默认是常量

常量池 Constant Pool

常量池:相同的值只存储一份,节省内存,共享访问
Java为很多基本类型的包装类/字符串常量都建立常量池

基本类型的包装类

  • Boolean,Byte,Short,Integer,Long,Character,Float,Double
  • Boolean: true, false
  • Byte:-128~127, Character : \u0000–\u007f (0—127)
  • Short, Int, Long:-128~127
  • Float,Double:没有缓存(常量池)

基本类型的包装类和字符串有两种创建方式:
常量式(字面量)赋值创建,放在栈内存 (将被常量化,栈内存)

Integer a = 10;
String b = “abc”;

new对象进行创建,放在堆内存 (不会常量化,堆内存)

Integer c = new Integer(10);
String d = new String(“abc”);

这两种创建方式导致创建的对象存放的位置不同

自动装箱 自动拆箱

不可变对象和字符串

不可变对象 Immutable Object

一旦创建,这个对象(状态/值)不能被更改了,内在的成员变量的值就不能修改了。

典型的不可变对象
-八个基本型别的包装类的对象
-String,BigInteger和BigDecimal等的对象

不可变对象传指针(引用)
由于不可变,临时对象指向新内存,外部实参的指针不改动
在这里插入图片描述
输出结果:
abc
abc
abc

如何创建不可变对象
-immutable对象是不可改变,有改变,请clone/new一个对
象进行修改
-所有的属性都是final和private的
-不提供setter方法
-类是final的,或者所有的方法都是final
-类中包含mutable对象,那么返回拷贝需要深度clone

不可变对象的优点
-只读,线程安全
-并发读,提高性能
-可以重复使用
缺点
-制造垃圾,浪费空间

可变对象Mutable Object

普通对象

字符串

String定义方法:
-常量赋值
-new对象,堆分配内存

字符串内容比较:equals方法
是否指向同一个对象:指针比较==

//字符串加法
String a=“abc”;
a = a+“def”; 

内存会产生abc以及abcdef,a指向后者,效率差
建议 append方法:
-StringBuffer(同步,线程安全,修改快速),
-StringBuilder(不同步,线程不安全,修改更快)

总结

-不可变对象提高读效率
-不可变对象设计的方法
-字符串append操作速度:StringBuilder>StringBuffer>String

第七章、package、import和classpath

java分布式放置和调用

package和import

放置在同一个目录下面的类,类之间的相互调用无需显式声明调用。
统一目录下类名不可以相同

Java支持多个目录放置Java,并且package/import/classpath/jar等机制配合使用,可以支持跨目录放置和调用Java类。

package 包,和C++中namespace类似

类全称(长名称)=包名+类名
短名称=类名
p.s.包名package name和目录层次一样,尽量唯一,常用域名

引用类(即import package)的时候,必须采用全称引用;程序正文可以用短名称

pakage 1.2
import 1.2.example
//可以采用 import 1.2.*//*不可递归到所有子程序
//若example和当前类在同一目录下,可以省略上句的import

import 1.2.ex

//也可以采用import

总结

-Java通过包(package)来分开类
-package必须和目录层次一样
-Java通过引用(import)来导入类
-import类尽量准确

jar文件导出和导入

jar文件是一组class文件的压缩包,类似于C++的DLL

jar文件优势
-jar文件可以包括多个class,比多层目录更加简洁实用
-jar文件经过压缩,只有一个文件,在网络下载和传播方面 ,更具有优势
-jar文件只包括class,而没有包含java文件,在保护源文件知 识版权方面,能够可以起到更好的作用
-将多个class文件压缩成jar文件(只有一个文件),可以规定给一个版本号,更容易进行版本控制

-利用IDE的Export功能导出jar文件
-使用JDK自带的jar.exe。jar.exe位于JAVA_HOME的bin目录下。

classpath

包的具体位置可以在编译和运行的时候通过classpath再指定

java -classpath .;c:\temp cn.com.test.Man
第一部分:java,执行命令,是java.exe的简写。
第二部分:-classpath 固定格式参数,可以简写成-cp
第三部分:是一个(Windows分号,Linux/Mac冒号连接起来的) 字符串。按分隔符隔开,得到一个个子路径。当运cn.com.test.Man类的过程中,如果需要用到其他的类,就会分裂第三部分的字符串,得到多个子路径,然后依次在每个路径下,再去寻找相应类(全称,包名以点隔开对应到目录)。
第四部分:主执行类的全称(含包名)

编译和运行规则

  • 编译一个类,需要java文件的全路径,包括扩展名。
  • 运行一个类,需写类名全称(非文件路径),无须写扩展名。
  • 编译类的时候,需要给出这个类所依赖的类(包括依赖的类再次 依赖的所有其他类)的所在路径。
  • 运行类的时候,需要给出这个类,以及被依赖类的路径总和。
  • classpath参数也可以包含jar包。如果路径内有空格,请将classpath 参数整体加双引号。
  • java -classpath “.;c:\test.jar;c:\temp;c:\a bc” cn.com.test.Man

总结

  • 包名和类所在的目录必须严格一致
  • 在命令行中,必须依靠classpath来指引所需要的类
  • 编译需要文件的全路径,运行需要类的完整名字

JAVA访问权限

JAVA访问权限:

  • private: 私有的,只能本类访问
  • default(通常忽略不写):同一个包内访问
  • protected:同一个包,子类均可以访问
  • public:公开的,所有类都可以访问

使用范围:

  • 四种都可以用来修饰成员变量、成员方法、构造函数
  • default和public可以修饰类

第八章、JAVA常用类

JAVA类库概述

  • 官方文档目前以英文为主
  • 可以下载文档离线版本(chm格式)
  • 这些文档原先是程序中的注释。利用JavaDoc技术,将这些 注释抽取出来,组织形成的以HTML为表现形式的API (Application Programming Interface,应用编程接口)文档。

Java类库

  • 包名以 java 开始的包是 Java 核心包 (Java Core Package)
  • 包名以 javax 开始的包是 Java 扩展包 (Java Extension Package)

数字相关类

java.math包
Java 数字类

  • 整数 Short, Int, Long
  • 浮点数 Float, Double
  • 大数类 BigInteger(大整数), BigDecimal(大浮点数)
  • 随机数类 Random
  • 工具类 Math

整数类型

  • short,16位,2个字节,有符号的以二进制补码表示的整数
    (-32768-32767, -215-215-1),默认值0
  • int, 32位,4个字节,有符号的以二进制补码表示的整数
    (-2147483648–2147483647, -231-231-1),默认值0
  • long, 64位,8个字节,有符号的以二进制补码表示的整数 -9,223,372,036,854,775,808(-263)~9,223,372,036,854,775,807(263 -1),默认值0L

浮点数类型

  • float,单精度,32位,4个字节,符合IEEE 754标准的浮点 数,默认值0.0f。float的范围为1.40129846432481707e-45 to 3.40282346638528860e+38 (无论正负)。
  • double,双精度,32位,4个字节,符合IEEE 754标准的浮 点数,默认值0.0d。double的范围为4.94065645841246544e324d to 1.79769313486231570e+308d (无论正负) 。
  • P.s.float和double都不能用来表示很精确的数字。

大数字类

  • 大整数类BigInteger –支持无限大的整数运算
  • 大浮点数BigDecimal –支持无限大的小数运算
  • P.s.注意精度和截断 –查看BigDecimalTest.java

随机数类

  • Random 随机数
  • nextInt() 返回一个随机int
  • nextInt(int a) 返回一个[0,a)之间的随机int
  • nextDouble()返回一个[0.0,1.0]之间double
  • ints 方法批量返回随机数数组

Math.random() 返回一个[0.0,1.0]之间double

数字工具类 • java.lang.Math:
绝对值函数abs;对数函数log;比较函数max、min;幂函数pow;四舍五入函数round等;向下取整floor;向上取整ceil

总结

  • 根据数字特点选择合适的类
  • 尽量使用类库自带的方法
  • 浮点数需要注意精度

字符串相关类

Java中使用频率最高的类,是一个不可变对象,加减操作性能较差

常见方法:charAt, concat, contains, endsWith,equals, equalsIgnoreCase, hashCode, indexOf, length, matches, replace, replaceAll, split, startsWith, subString, trim, valueOf

可变字符串

  • StringBuffer(字符串加减,同步,性能好)
  • StringBuilder(字符串加减,不同步,性能更好)

StringBuffer/StringBuilder: 方法一样,区别在同步

  • append/insert/delete/replace/substring
  • length 字符串实际大小,capacity字符串占用空间大小
  • trimToSize(): 去除空隙,将字符串存储压缩到实际大小
  • P.s.如有大量append,事先预估大小,再调用相应构造函数
    StringBuffer初始大小为(16+初始字符串长度)

时间相关类

Calendar;抽象类

Calendar gc=Calendar.getInstance(); 

Calendar gc= new GregorianCalendar(); 
  • get(Field) 来获取时间中每个属性的值. 注意,月份0-11.
  • getTime()返回相应的Date对象 –getTimeInMillis(), 返回自1970.1.1以来的毫秒数
  • set(Field) 设置时间字段
  • add(field, amount) 根据指定字段增加/减少时间
  • roll(field, amount) 根据指定字段增加/减少时间,但不影响上一级的时间段

java.time包:新的Java日期/时间API的基础包

  • java.time.chrono包:为非ISO的日历系统定义了一些泛化的API
  • java.time.format包:格式化和解析日期时间对象的类
  • java.time.temporal包:包含一些时态对象,可以用其找 出关于日期/时间对象的某个特定日期或时间
  • java.time.zone包:包含支持不同时区以及相关规则的类

java.time包主要类

  • LocalDate:日期类
  • LocalTime:时间类(时分秒-纳秒)
  • LocalDateTime: LocalDate + LocalTime
  • Instant: 时间戳

格式化相关类

java.text包java.text.Format的子类

  • NumberFormat:数字格式化,抽象类;DecimalFormat工厂模式
    例如:将1234567格式化输出为1,234,567
  • MessageFormat:字符串格式化
    -支持多个参数值对位复制文本
    -支持变量的自定义格式
    例如将”Hello {1}”根据变量值格式化为Hello World
  • DateFormat:日期/时间格式化,抽象类;SimpleDateFormat工厂模式
    -parse:将字符串格式化为时间对象
    -format:将时间对象格式化为字符串
    如将当前时间转为化YYYY-MM-DD HH24:MI:SS输出

java.time.format包下

  • DateTimeFormatter,时间格式化

    线程安全(vs SimpleDateFormat 线程不安全)

java.time.format.DateFormatter:

  • ofPattern: 设定时间格式
  • parse:将字符串格式化为时间对象
  • format:将时间对象格式化为字符串
    如将当前时间转为化YYYY-MM-DD HH24:MI:SS输出
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!