Java基础快速巩固
目录
9.覆写(Override)与多态(polymorphic)
1.Java来源 介绍
Java版本
- Java SE:Java Standard Edition
- Java EE:Java Enterprise Edition
- Java ME:Java Micro Edition (使用较少)
关系图如下:JavaEE是大哥
Java规范(确保Java跨平台特性)
- JSR规范:Java Specification Request
- JCP组织:Java Community Process
Java框架布局
2.Java变量类型(基本类型&引用类型)
基本类型:整型、浮点型、布尔型、字符型(Java使用unicode表示字符)
字符操作如下图:
引用类型:包装类(Integer、Double等)、String(注意String=""和String=null的区别)、自定义类型等
String操作如下图:
注:
- 变量可重新赋值,等号是赋值符号,不是数学意义的符号
- 常量在初始化后不能再被赋值
- 使用常量方便来理解程序意图
- 引用类型在使用的过程中要特别注意 (常常是比较隐含的问题)
整型
- byte:8位,1字节
- short:16位,2字节
- int:32位,4字节
- long:64位,8字节
整型的详细信息见下图:
基本类型运算注意事项
- 计算结果溢出不报错——解决方案:使用更大的基本类型
- 计算结果不正确不报错
实例如下图:
总结
- 区分字符类型(基本类型)和字符串类型(引用类型)
- 基本类型的变量是“持有”某个数值
- 引用类型的变量是“指向”某个对象
- 引用类型的变量可以是null
- 区分空(null)和空字符串("")
3.位运算与逻辑运算
位运算 (注意有符号|无符号问题)
无符号右移>>,有符号右移>>> (有符号位移要保留符号位)
&、| 运算
异或运算
总结
- &&运算和||运算是短路运算,即第一个条件符合要求第二个条件不执行
- 布尔类型计算结果仍是布尔类型
- 三元运算符b?x:y 后面的类型必须相同
4.强制类型转换(基本类型)
向下转型
- 不需要强转,Java会自动转型提升
向上转型
- 在运算过程中,计算结果为较大型的类型需要强制转换
- 可以强转类型:变量、数值
- 强转可能丢失精度
注:自动或强制类型转换主要看是否会造成失真,if会就要强制;else就自动类型转换
整数强制转换注意事项
- 整型可以自动提升为浮点型
- 浮点数强转为整型会直接丢掉小数位——>如果浮点数特别大,强制转型会得到int的最大值
- 四舍五入的技巧(如下图) +0.5再强转int
浮点数强转换注意事项(详见下图)
- 很多浮点数无法精确表示
- 计算有误差
- 注意类型不自动提升的情况
总结
- 整数运算永远精确
- 浮点数运算无法精确表示,运算结果可能失真
- 运算结果会自动提升
- 可以强制转型,但可能丢失精度
- 选择合适范围的类型(int、long、double等)
5.数组
直接总结
- 数组是同一数据类型的集合
- 数组是引用类型
- 数组元素是值类型或引用类型
- 数组一旦创建大小不可变
- 可以通过索引访问数组元素
- 索引超出范围就报错
6.面向对象
面向对象概述
面向对象编程:Object-Oriented Programming
对现实世界建立计算机模型的一种编程方法
class&instance
- class定义如何创建实例,class名字就是数据类型
- instance是根据class创建的对象实例, 可以创建多个instance,各个instance类型相同,但各自属性可能不同
方法
- 方法可以让外部代码安全的访问实例字段
- 方法是一组执行语句
- 方法内部遇到return时返回
- void表示不返回类型,注意和返回null的区别
- 外部代码通过public方法操作实例
- 内部代码可以调用private方法
重载方法
- 重载方法应该完成相同的功能,参考Java中String中的indexOf()方法
- 重载方法主要依靠参数类型和数量区分
- 不要去交换参数顺序
- 重载方法返回值类型应该相同
super
- super关键字表示父类(超类)
- 构造方法的第一行语句必须调用super(),若没有super()编译器会自动生成super()
- 如果父类没有默认构造方法,子类必须显示调用super()
详情见下图:
7.可塑性(自定义类型)
向上可塑性(向上转型)
向下可塑性(向下转型)
- 可以对实例变量进行向下转型(downcasting)
- 向下转型把抽象的类型变成一个具体的类型
- 向下转型很可能报错:ClassCastException
- instanceof操作符可以判断对象的类型
- 向下转型前可以用instanceof判断,避免异常。如下图:
8.继承和组合
- 继承是is关系
- 组合是has关系
如下图: Student不宜从Book继承,Student可以持有一个Book实例——低耦合
总结
- 继承是面向对象编程的一种代码复用方式
- Java只允许单继承
- protected允许子类访问父类的字段和方法
- 子类的构造方法可以通过super()调用父类的构造方法
- 可以安全的向上转型为更加抽象的类型
- 可以强制向下转型,最好借助instanceof判断,避免报错
- 子类和父类的关系是is,has关系不能用继承
9.覆写(Override)与多态(polymorphic)
Override
- 子类覆写父类的方法是覆写
- 方法签名如果不同就不是Override,而是创建一个新方法
- 加上@Override可以让编译器帮助检查是否进行了正确的覆写
- @Overrdie不是必须的
- 引用变量的声明类型可能与其实际类型不符
- 实例对象的方法调用总是对应实际类型
- Java的实际方法调用是基于运行时实际类型的动态调用,详情如下图:
Object中的方法覆写
- toString:把instance输出为String
- equals :判断两个instance是否逻辑相同
- hashCode:计算一个instance的哈希值
Super方法调用覆写
- Super方法可以调用父类被覆写的方法,如下图:
final注意事项
- 用final修饰的方法不能被Override
- 用final修饰的类不能被继承
- 用final修饰的字段在初始化后不能被修改
Polymorphic
- 多态是指针对某个类型的方法调用,其真正执行的方法取决于运行时实际类型的方法
- 对某个类型调用某个方法,执行的方法可能是某个子类的覆写方法
- 利用多态,允许添加更多类型的子类实现功能扩展
总结
- 子类可以覆写父类的方法(Override)
- 覆写在子类中改变了父类方法的行为
- 多态:Java的方法调用总是作用于对象的实际类型
- final修饰的方法可以阻止被覆写
- final修饰的class可以阻止被继承
- final修饰的field必须在创建对象时初始化
9.抽象类与接口
9.1 抽象
抽象方法&抽象类
如果一个class定义了方法,但没有具体执行代码,这个方法就是抽象方法:
- 抽象方法用abstract修饰
- 抽象方法没有任何执行语句
- 因为无法执行抽象方法,因此这个类也必须声明为抽象类(abstract class)
- 无法实例化一个抽象类
问:无法实例化一个抽象类有什么用?
- 抽象类用于被继承
- 抽象类强迫子类实现其定义的抽象方法(否则编译错误)
- 抽象方法实际上相当于定义了“规范”
问:面向抽象编程的本质?
- 上层代码只定义规范(abstract class)
- 不需要子类就可以实现业务逻辑(正常编译)
- 具体的业务逻辑由不同的子类实现,调用者不必关心
抽象总结
- 抽象方法定义了子类必须实现的接口规范
- 定义了抽象方法的类就是抽象类
- 从抽象类继承的子类必须实现抽象方法
- 如果不实现抽象方法,则该子类仍是一个抽象类
9.2 接口(Interface)
Interface概述
如果一个抽象类没有字段,所有方法全部是抽象方法,就可以把该抽象类改写为接口:
- 使用interface声明一个接口
- 接口定义的方法默认是public abstract(不需要写)
- 一个interface可以继承另一个interface,使用extends;相当于扩展了接口的方法
术语区分:
- Java的接口特指interface定义的接口,只定义方法签名
- 编程接口泛指接口规范,如方法签名、数据格式、网络协议等
抽象类与接口比较
接口中定义default方法如下:
继承设计
- 合理设计interface和abstract class的继承关系
- 公共逻辑放在abstract class
- 接口层次代表抽象程度
如Java中的容器继承结构如下:
接口总结
- 接口定义了纯抽象规范
- 类可以实现多个接口
- 接口也是数据类型,使用于向上转型和向下转型
- 接口不能定义实例字段
- 接口可以定义default方法(JDK>=1.8)
10.静态
静态字段
- 所有实例共享一个静态字段
- 不推荐用实例变量访问静态字段
- 推荐用类名访问静态字段
- 可以把静态字段理解为描述class本身的字段(非实例字段)
相关代码如下:
静态方法
- 静态方法不能访问this变量
- 静态方法不能访问实例字段
- 静态方法可以访问静态字段
- 静态方法经常用于工具类,如:
- Arrays.sort( )
- Math.random( )
- 静态方法经常用于辅助方法
- Java程序的入口main()也是静态方法
总结
- 静态字段属于所有实例“共享”的字段,实际上是属于class的字段
- 调用静态方法不需要实例,因此无法访问this
- 静态方法可以访问静态字段和静态方法
- 静态方法常用工具类和辅助方法
11.访问权限
概述
- Java的类、接口、字段和方法都可以设置访问权限
- 访问权限是指在一个类的内部,能否引用另一个类以及访问它的字段和方法
- 访问劝降有public、protected、private、packeage四种
package
- JVM只看完整类名,只要包名不同类就不同,包可以是多层结构,没有父子关系
- JVM加载class并执行代码时,总是使用class的完整类名,编译器编译后的class文件中全部是完整类名
- 包作用域:位于同一个包的类,可以访问没有public、private修饰的class;可以访问没有public、protected、private修饰的的字段和方法。如下图:
- 引用其他类的方法:使用完整类名;先import再使用类名;可以使用*(不推荐)
实践注意事项
- 如果不确定是否需要public,就不声明为public,要尽可能少暴露对外方法
- 尽可能把局部变量的作用域缩小
- 尽可能延后声明局部变量
final
- final与访问权限不冲突
- 用final修饰class可以阻止被继承
- 用final修饰method可以阻止被覆写
- 用final修饰field可以阻止被重新赋值
- 用final修饰局部变量可以阻止被重新赋值
总结
- Java内建的访问权限包括public、protected、private、package
- Java在方法内部定义的变量是局部变量
- 局部变量的作用域从变量声明开始到一个块结束
- final修饰符不是访问权限
- 一个java文件只能包含一个public class,但可以包含多个非public class
11. 环境变量classpath
classpath概述
- classpath是一个环境变量
- classpath指示JVM如何搜索class
- classpath设置的搜索路径与操作系统相关
classpath的设置方法
- 直接在系统环境中设置classpath环境变量(不推荐)
- 在启动JVM时设置classpath变量(推荐) java -cp 设置环境变量 包名+类名 ,例如:java -cp C:\work com.sc.Hello
- 没有设置环境变量,也没有设置-cp参数,默认的classpath为当前目录
- 在Eclipse中运行的Java程序,Eclipse自动传入的-cp参数是当前工程的bin目录和引入的jar
12.jar包
jar包概述
- jar包是zip格式的压缩文件,包含若干.class文件
- jar包相当于目录
- classpath可以包含jar文件:c:\work\bin\all.jar
- 查找类会在相应的jar文件中搜索.class文件
jar包的创建方法
- 使用JDK自带的jar命令,创建机制如下:
- JVM运行时会自动加载JDK自带的class
- JDK自带的class被打包在rt.jar
- 不需要在classpath中引用rt.jar
- 使用构建工具如Maven等
jar包的功能
- jar包可以包含一个特殊的/META-INF/MANIFEST.MF文件
- MANIFEST.MF是纯文件,可以指定Main-Class和其他信息
- jar包可以包含其他jar包
jar包打包步骤如下
(1)创建java项目
(2)创建/META-INF/MANIFEST.MF文件 ——关于MANIFEST.MF文件的内容信息详情请点击查看
(3)在工程目录下手动打包bin目录下的所有文件
(4)DOS下运行
以上是Java的基础知识汇总,持续关注还有进一步的java进阶更新!点击☞Java基础工具类了解更多java基础知识。
谢谢阅读 ---知飞翀