导图社区 Java继承与多态
Java语言的继承与多态部分。
编辑于2018-12-01 13:03:52Java
Java语言 “一次编译 到处运行”的方式,有效地解决了目前大多数高级程序设计语言需要针对不同系统来编译产生不同机器代码的问题,即硬件环境和操作系统平台的异构问题,大大降低了程序开发、维护和管理的开销。
主题
数据类型和运算符
关键字和标识符
标识符:由字母,数字,下划线和美元符号组成
数字不开头,Java是大小写敏感的语言
关键字,保留字
Java中定义了50个关键字: abstract class extends import private switch volatile assert const final instanceof protected synchronized while boolean continue finally int public this break default float interface return throw byte do for long short throws case double goto native static transient catch else if new strictfp try char enum implements package super void Java中还有保留字。现在并未被使用,但在以后的版本中有可能作为关键字。 goto const 虽为关键字,但并未被使用,它们被用作保留字,以备扩充。 strictfp 是从1.2版本起开始使用的 enum和assert分别是从5.0和1.4 版本中引入的 还有3个用于表示特殊值的保留字: true false null 现在Java中的保留字包括: byValue cast false future generic inner operator outer rest var goto const null
数据类型
基本类型
又称原始数据类型,简单类型,是不能简化的、内置的数据类型,由编程语言本身定义
布尔类型
默认为false
数值类型
byte short int long float double char
引用数据类型
又称复合类型,扩展类型 一般都是通过类或者接口进行构造,类提供了捆绑数据和方法的方式,同时可以针对程序外部进行信息隐藏
强制数据转换
转换顺序 (前至后) char int long float double byte short int long float double
常量与变量
常量
常量的作用:代表常数,便于程序的修改 增强程序的可读性
整型常量
浮点型常量
字符常量
变量
变量使用前必须首先声明
运算符
赋值运算符 =
算术运算符 + - * /(整数相除的结果为整数) %
关系运算符 > >= < < != 关系条件成立用true表示
位运算符
& 位与
清零
去一个数中指定的位
| 位或
常用来对一个数据的某些位置1
^ 位的异或
使特定位翻转
与0相异或,保留原值
~ 位的非
使二进制按位取反
<< 左移位运算符
即乘2
>> 有符号右移运算符
采用符号扩展机制,值为正,在高位补0,值为负,在高位补1
>>> 无符号右移运算符
采用零扩展,无论值为正还是负,都在高位补0
逻辑运算符
! NOT
&& AND
|| OR
其他运算符
复合运算符
如 += 提高效率
条件运算符
表达式1?表达式2:表达式3
表达式1 2 3 类型可以不同,此时条件表达式的值为它们中精度较高的类型
逗号运算符
用逗号分开的表达式的值分别结算,但整个表达式的值是最后一个表达式的值。在Java中只能用在for循环语句中
字符串运算符
+ 不仅起到连接不同字符串的作用,还有一种隐式的转型功能
数据类型转换
自动类型转换
byte - short(char)- int - long - float - double
byte short char三者并不会互相转换,三者在计算中首先转换为int型
强制类型转换
必须编写代码,很可能会存在精度的损失
程序流程控制
分支结构
if语句
if-else语句
switch语句
循环结构
while语句
先判断后执行 while括号中的表达式必须是布尔型 循环体可以为空体
do-while语句
先执行一次再判断 先执行循环体在计算布尔表达式
for语句
语句嵌套
while嵌套
do-while嵌套
for循环嵌套
相互嵌套
程序跳转
break语句
跳出该区块,继续运行后面的语句 用于循环 表示跳出break所在的循环
continue
只能用于循环结构
不带标号时提前结束本次循环,进入下一轮循环的运行 直接跳到判断语句中
带标号的continue[标号]多用于多重循环结构,一般需要放在整个循环的外面,一旦内循环执行了带标号的continue语句,程序直接跳转到标号处的外层循环。
return
多用在方法中,有两个作用
返回方法指定类型的值
结束方法的执行
常用的程序设计方法
枚举法(穷举法)
递推法
顺推
逆推
递归法
类与对象
基本概念
实体映射对象
对象抽象出类
类实例化对象
实体抽象出类型概念
类型概念映射类
面向对象的特性
封装
继承
单继承
任何一个派生类都只有一个直接父类 树状结构 Java仅支持单继承
多继承
一个派生类可以有一个以上的直接父类 网状结构
多态
重载
静态多态 同一个类中定义多个名称相同的方法
覆盖
动态多态 子类中定义与父类中同名的方法
类与对象
类
类的修饰符只有3个:public private protected
final 和 abstract 不能同时出现
类的父类写在extends 后,该类实现的接口写在implements 后
对象
对象的声明 格式: 类名 对象变量名
声明部位对象分配空间,只为引用型变量分配一个引用空间,用来存放引用值(该类型对象的地址)
创建对象(给实例分配内存空间的过程) 格式: new类名([实参表])
Java中可以通过.实现对变量的访问和方法的调用
引用成员变量的格式: 对象变量名.成员变量名
引用成员方法的格式: 对象变量名.成员方法名([参数表])
对象的清除指当不存在某一对象的引用时,就释放该对象所占用的内存空间
Java中的对象清除由运行系统自动完成,成为垃圾收集
成员变量
成员变量的声明
格式: [可访问修饰符][abstract|final][其他] 类型变量名[=初始化表达式]...
可访问修饰符定义被访问的范围:public,protected,private和默认(缺省)
被static修饰的成员变量称为类变量(或静态变量),没有被static修饰成员变量称为实例变量。类变量属于类,实例变量属于对象(或实例)
被final修饰的变量通常称为有名常量,与普通变量不同的是,有名常量必须赋值且只能赋值一次,之后有名常量的值不能再被修改
其他是指transient 和 volatile
transient:定义一个暂时变量,指示Java虚拟机该变量不是对象永久状态的一部分,在对象序列化时不需要考虑
volatile:定义一个共享变量,告诉Java编译器该变量的值可能会被当前线程以外的其他线程所改变
实例变量和类变量
实例变量:类体内方法体外定义,且无static修饰符
实例变量位于堆区,实例变量的生命周期与实例的生命周期相同
类变量:类体内方法体外定义,变量名前需要static修饰符
类变量位于方法区,类变量属于类,不属于任何一个类的具体对象
局部变量:方法体内或块内定义的,变量名前只能用final修饰或没有修饰符
局部变量属于栈区
访问类变量的两种方式
通过类名访问
通过类的任何实例变量访问
变量的初始化
变量的初始化指自变量定义以后,首次给它赋初始值的过程
初始化为默认值的规则
整数型(byte int long short)的基本类型变量的默认值为0
单精度浮点型(float)的基本类型变量的默认值为0.0f
双精度浮点型(double)的基本类型变量的默认值为0.0d
字符型(char)的基本类型变量的默认值为“\u0000”,即空字符
布尔型的基本类型变量的默认值为false
数组引用类型的变量的默认值为null
显式初始化
定义: 一个变量在定义时包含初始化表达式,那么系统会随后计算该表达式并给变量重新赋值
局部变量必须先经过显式初始化,才能够使用。若没有被显式初始化,编译器将报错
报错及解决办法
局部变量的错误引用
编译时报错
解决方法:局部变量在引用前赋值
成员变量的错误引用
编译时报错
变量赋值放在方法中
局部变量、实例变量和类变量
局部变量
在方法每次调用时重新初始化,使用前一定要显式初始化或赋值
实例变量
实例变量有默认值,可以通过构造方法进行初始化或者动态初始化块进行初始化
动态初始化块格式{....} 大括号前无修饰符
类变量
类变量的初始化发生在类装入时。类变量有默认值,可以通过静态初始化块进行初始化
静态初始化块格式:static{...}
final修饰符说明常量时,应注意
需要说明常量的数据类型
final常用于修饰类变量
若一个final变量在定义时没有包含初始化表达式,那么应在适当的时候为其显式赋值
final实例变量:必须在某个实例初始化块或者在每个构造方法内显式赋值
final类变量:必须在某个静态初始化块内显式赋值
final局部变量:必须在引用之前显式赋值
变量的作用域和生存期
变量的生存期lifetime指变量被分配内存的时间期限
类变量的生存期与类相同
实例变量的生存期与实例(对象)相同
局部变量当其所在方法被调用时,为该局部变量分配内存空间,方法结束调用时,收回该局部变量所占内存空间
成员方法
成员方法的声明及调用
格式:[可访问修饰符][abstract][static][final][native][synchronize] 返回类型方法名(形参表)[throw 异常类名表]{...//方法体}
格式的含义
修饰符
可访问修饰符与成员变量可访问修饰符含义相同
用abstract修饰方法称为抽象方法,只提供方法名、形参表和返回类型,没有方法体的方法
有static修饰的称为类方法,否则称为实例方法
有final修饰的方法称为最终方法
最终方法不能在子类中覆盖
最终方法不能被abstract修饰
private方法和final类中的所有方法都隐含final性质
用native修饰的方法称为本地方法
用synchronize修饰的方法称为同步方法,用于保证多线程之间的同步性
返回类型
返回值类型
基本类型
引用类型
void指明该方法没有返回值
返回值非void,则方法体中必须包含带表达式的return语句语句返回的数据类型与方法的返回类型相容
对基本类型,实际返回类型要与制定返回类型相同,或者能够赋值转换成制定返回类型
对引用类型(类),实际返回类型要与指定返回类型相同(同一个类),或者是指定返回类型的一个子类
形参表,可有可无
有形参:各参数用逗号隔开 方法形参被看作时局部变量
方法调用时,实参要与形参数目相同,类型相容
实参与形参的传递规则
基本类型,按值传递;引用类型,按引用传递
方法体,并列形式
抽象方法和本地方法,方法体为分号
其他情况,方法体是块语句
实例方法和类方法
调用方式不同
实例方法必须通过实例调用
类方法一般通过类名调用,也可以通过实例调用
访问的成员不同
实例方法可以直接访问该类的实例变量与实例方法,也可以访问类变量与类方法
类方法只能访问该类的类变量和类方法,不能直接访问实例变量和实例方法
构造方法
具体功能
为实例分配内存空间
初始化实例变量
返回对该实例的一个引用
方法重载
含义:一个类中出现多个方法名相同但形参不同的情况
形参不同
参数类型不同
参数顺序不同
参数个数不同
数据传递
方式
参数传递
Java参数传递的本质是值传递
参数为基本类型:按值传递 特点为数据单向传递
参数为引用类型:按引用值传递 特点是 引用值单向传递,数据双向传递
方法返回
方法调用后被调方法将求出的值返回到调用方法处
实例变量
作为对象中诸方法的共享变量来传送数据
类变量
作为同一类中所有对象诸方法的共享变量来传送数据
类的组织方式—包
作用
包可以划分和组织类,使类和接口按功能、来源分为不同的集合
包是类名空间,一个包中的类不能重名,不同包中的类可以重名
包提供了包一级的封装与存取权限
包的创建
package 包名
功能:指明源文件中定义的类和接口属于哪个包
无名默认包的类不能被其他包中的类引用
包的引用
若一个类访问来自另一个包(Java.lang包除外)中的类,那么前者必须通过通过语句把这个类引入。否则必须引入这个类的完整类名
引用格式
import 包名.类名;
import 包名.*;
访问权限
Java中类,包和访问修饰符共同构建了Java的访问控制机制
类的访问权限
用public修饰
该类可以被任何包的代码访问
缺省修饰
该类可被本包的代码访问
类中成员的访问控制
私有(private)成员
仅在本类内中的代码可访问它
默认(无修饰符成员)成员
在同一包内中的代码可访问它
保护(protected)成员
同一包内及其子类(不同包)中的代码可访问它
公共(public)成员
在所有包内中的代码可访问它
继承与多态
继承的实现
通过extends实现
格式:[修饰符]class 子类名 extends 父类名{成员变量定义 构造方法定义 静态或实例初始化块 成员方法定义}
Java仅支持单继承,一个final类不能够有子类
所有类都是Object类的子类
直接引用是直接使用变量名或方法名
在一个类中,不能被继承的内容
私有成员
静态初始化块
父类和子类不在同一个包中,父类中没有用被protected,public修饰的成员
在父类或超类中用修饰符final或static修饰的方法不能被子类继承
变量隐藏和方法覆盖
变量隐藏
子类的成员变量名与父类的成员变量名同名,使得父类中的成员变量不能被子类直接引用
出现变量隐藏时,要在子类中直接引用超类中被隐藏的变量,可以使用包含关键字super的方法访问表达式 super.变量名
方法覆盖
子类定义的实例方法与直接超类中的某个实例方法具有相同的方法名,返回值和完全一致的参数,使得直接子类中的那个方法不能被子类直接引用
一个正确的方法覆盖需要满足的要求
覆盖方法与被覆盖方法的返回类型,方法名,参数要完全一致
覆盖方法的访问级别不能低于被覆盖方法的访问级别
覆盖方法不能比被覆盖方法抛出更多的‘受检查异常’的类型
意义
在不改变变量名和方法名的基础上(对外统一名字和接口)通过变量隐藏和方法覆盖可以把父类的状态和行为改变成自身的状态和行为,又不失其继承性
子主题
通过引用类型变量来访问所引用对象的方法变量时,Java采用不同的绑定规则
动态绑定
实例方法与引用变量实际引用的对象的方法绑定
静态绑定
成员变量与引用变量所声明的类型的成员变量绑定
静态方法与引用变量所声明的类型的方法绑定
子类的构造方法
有继承时的构造方法
子类不能继承父类的构造方法,但其存在一定的关系,并遵守以下原则
子类没有定义任何构造方法时在创建子类对象时会调用父类无参构造方法,即执行super()
子类定义了构造方法
在子类构造方法中没有显式调用父类的构造方法
在创建子类对象时会先调用父类无参构造方法,再执行子类自己的构造方法
在子类构造方法中利用super关键字显式调用父类的构造方法
在创建子类对象时,首先显式调用父类的构造方法,然后执行子类构造方法体其余的部分
关键字null,this和super
null
空对象
this
代表了当前对象的一个引用,引用场合
用this代表当前对象本身
this.变量名
在类的构造方法中,通过this语句调用本类的另一个构造方法 this([实参表])
super
super.变量名
supr.方法名
super([实参表])
构造方法的功能
在创建类的对象时进行初始化工作
在创建对象时,不仅会建立在该类中定义的实例变量,也会建立在该类的所有超类中定义的实例变量(不管是否被继承) 如何初始化?
子类的构造方法初始化子类中定义的实例变量,超类的构造方法初始化超类中定义的实例变量
抽象类和最终类
抽象
抽象方法
abstract 返回类型 方法名(形参表); 分号代表一个方法体的定义
抽象类
抽象类是abstract修饰的类,不能生成对象的类,其意义在于继承
要求
抽象类可以没有抽象方法,反抽象方法一定定义在抽象类中
抽象类一般含有抽象方法,需要子类继承
抽象类还可以含有非抽象的
抽象类不能定义为private final和static
没有抽象的构造方法
最终类
final可以修饰非抽象类,非抽象成员方法和变量
用final修饰的非抽象类不能被继承,没有子类,被称为最终类
用final修饰的非抽象方法不能被子类的方法覆盖,称为最终方法
用final修饰的变量或常量只能被赋一次值
接口
定义
接口中只包含有名常量和没有实现的抽象方法
格式:public interface 接口名 [extends 直接付接口名列表]{[public static final ]类型 有名常量名=常量值; [public abstract ]返回值类型 方法名(参数列表)}
接口默认有public、abstract属性
接口定义的是某一特定功能的一组方法的对外接口和规范
实现
把对接口的继承称为接口的实现
一个类可以实现一个或多个接口,接口在类定义中的implements子句中列出
格式:[修饰符] class 类名 [extends 直接超类名] implements直接超接口名列表{...}
规则
在类定义中,用implements声明该类将要实现哪些接口
实现类的方法必须指定为public,否则认为缩小权限范围
类中必须具体实现该interface中定义的抽象方法
若实现的接口不是抽象类,那么必须实现该interface中定义的全部方法,也可以是空方法体
若实现接口的类是抽象类,那么可以不实现该interface中定义的全部方法
接口的继承与组合
接口通过extends继承其他接口
接口怒允许循环继承或继承自己
多态
一个名字,多种方法
方法重载实现多态
方法覆盖实现多态
适配器设计模式(包装模式)
实现接口转换
内部类(嵌套类)
在一个类内部定义的类。把内部类所在的类称为外部类,最外层的类称为顶层类
顶层类只能处于public和没有修饰符的访问级别,成员内部类可以处于public,protected,private和无修饰符这四种访问级别
分类
成员内部类
一个内部类被声明为一个类的成员
内部类应与外部类不重名
局部内部类
内部类被定义在一个类的方法中或代码块中
匿名内部类
定义在方法体或块语句中的内部类,无类名
通过扩展某个类或实现某个接口来定义 无构造方法
格式:new 超类名或接口名 (参数列表){类定义};
匿名内部类是局部
数组与字符串
概述
Java语言特点
Java语言是一种简单的、面向对象的、分布的、解释的、健壮的、安全的、体系结构中立的、可移植的、高性能的、多线程的以及动态执行的程序设计语言
简单易学
语法与C语言、C++语言很接近,但Java丢弃了C++中复杂、不安全的特性,比如:操作符重载、多继承、重载等
面向对象
Java语言是一种完全面向对象的程序设计语言。具有面向对象的封装、多态和继承三大特点。 Java语言通过类实现封装;在类之间实现单继承,在接口之间实现多继承,支持类与接口之间的实现机制(关键字为implements);并全面支持动态绑定实现多态
安全性
除了Java语言具有的许多安全特性外,Java还提供了字节码校验器、文件访问限制机制、类装载器和运行时内存布局司机安全保证机制
跨平台(体系结构中立)
Java程序能在网络上任何地方执行;语言版本完全统一,实现了平台无关性;具有字节代码与平台无关性;有访问底层操作系统功能的拓展类库,不依赖于具体实现系统等。Java编译器是用Java实现的,Java的运行环境使用ANSI C实现的
多线程
Java环境本身就是多线程,特别的 Java提供了对多线程的语言级支持,程序员能很方便的编写多线程应用程序
动态性
Java所需要的类是运行时动态装载的,也可以从网络载入
健壮性
Java的强类型机制、异常处理、垃圾自动收集等是Java程序健壮性的重要保证。Java的安全检查机制使得Java更具健壮性
Java程序开发步骤
1.创建、编辑Java源文件
2.编译Java源文件
3.运行Java字节码文件
Java虚拟机规范规定
Java虚拟机由6个部分组成
一组指令集,一组寄存器,一个类文件格式规定,一个栈,一个无用单元收集堆和一个方法区域
虚拟机能够认识的字节代码以及能实现的功能
但Java虚拟机没有规定Java虚拟机组织结构及其功能是如何实现的,而这些必须在真实机器上以某种方式实现,可以是软件,也可以是硬件。 Java平台由Java虚拟机和Java应用编程接口构成 Java程序只需要编译一次就可以在各种系统上运行
Java程序的跨平台性的原因
Java程序的跨平台主要是指字节码文件可以在任何具有Java虚拟机的计算机或者电子设备上正确运行
1.Java语言是完全统一的语言版本
2.字节代码是与平台无关的
3.Java虚拟机隐藏了不同平台的差异
Java虚拟机保证了字节码文件运行的正确性
Java的三个体系
JavaSE (标准版)
JavaEE (企业版)
JavaME (微型版)
Java常用类
图形用户界面GUI
多线程
输入输出流
数据库编程
异常处理