如若文章中出现冲突,或者出现错误,请联系 QQ:2669157689 指出我的问题。谢谢~
介绍Java中类的继承,封装,多态,方法的覆盖,抽象类、接口及内部类等面向对象的高级特性。通过本课的学习,我们应该掌握如下知识:
- 类的继承、封装、多态
- 抽象类及接口
- 引用数据类型的转换
- 访问权限修饰符的使用
- final关键字
JAVA编程基础 —— 面向对象高级特性
1. 类的继承
① 类的继承
- 在 Java 中定义一个类时,让该类通过关键字 extends 继承一个已有的类,这就是类的继承(泛化)
- 被继承的类称为父类(超类,基类),新的类称为子类(派生类)
- 子类继承父类的所有属性和方法,同时也可以增加自己的属性和方法
② 继承的语法和规则
- 继承的语法
[修饰符] class 子类名 extends 父类名
- 继承的优点:使编码更高效、易维护、代码的重用
- 继承的规则:
- Java中只支持单继承,也就是说每个类只能有一个父类,不允许有多重继承
- 一个父类可以有多个子类
- 子类继承父类所有的属性和方法
③ 子类实例化的过程
- 子类实例化时先实例化其父类,然后实例化子类
- 要先调用父类的构造器,父类构造器运行完毕,才调用子类的构造器
- 子类的构造器 — 子类不能继承父类的构造器
- 使用默认的构造器.
- 在子类中的创建构造器
- 在子类中创建构造器时,必须调用父类的构造器
- 子类可以在自己的构造器中使用 super 关键字来调用父类的构造器
super (参数1,参数2,…);
- 如果使用super关键字调用父类构造器,必须写在该子类构造器的第一行
- 如调用的是父类中无参的构造器,则可以不写
super()
- 如果子类中调用了父类无参的构造器,而父类中没有无参构造器则系统编译出错
④ super和this关键字
super()
- 作用:调用父类的构造器、指向父类的引用
- 只能出现在子类的构造器中,且必须是第一行
super()
中的参数,决定了调用父类哪个构造器- 如果子类构造器中没有出现 super,那么编译器会默认加上
super()
,即调用父类的空构造器,如果父类没有空构造器,编译器提示错误
this()
- 作用:调用本类的构造器、指向本类的引用
- 只能写在构造器的第一行
- 在同一个构造器中
super()
和this()
不能同时出现
2. Java包的概念
① Java中的包
- 包的概念及应用
- 在Java中,包主要有以下用途 :
- 包允许将类组合成较小的单元
- 有助于避免命名冲突
- 包允许在更广的范围内保护类、数据和方法
- 包可以是类、接口和子包的集合
- 在Java中,包主要有以下用途 :
- 包的概念及应用
- 将类放入包中
package 包名;
- 注意:
- 在 java 中位于包中的类,在文件系统中的存放位置,必须有与包名层次相对应的目录结构
- package 语句作为 java 源文件的第一条语句
- 每个源文件只能声明一个包
- 如果没有 package 语句,则默认为无名包
- 将类放入包中
② Java中常用的包
java.lang
— Java语言包,任何程序中,该包都被自动导入java.awt
— 图形用户界面包java.awt.event
— 图形用户界面事件处理包java.swing
— 跨平台轻量级组件包java.sql
— 数据库访问包java.io
— 这个包由对您的输入/输出操作有用的类组成java.util
— 该包提供了许多创建如:lists, calendar,date 等所需要的类和接口java.net
— 该包提供了许多进行 TCP / IP 网络编程的类和接口
③ import导入包中的类
- 访问其它包中的类
- 包名.路径名
package test; class Cat extends p08.Animal{…}
- 使用import关键字引入其它包中的类
package test; import p08.Animal; class Cat extends Animal{…}
- 位于同一包中的类可以直接访问
- 导入包中所有的类
import 包名.*;
- 导入子包中所有的类
import 包名.子包名.*;
- 导入包中的某个类
import 包名.子包名.类名;
- 包名.路径名
3. 访问权限修饰符
① 封装:隐藏属性、方法或实现细节的过程称为封装
- 信息隐藏,隐藏对象的实现细节,不让用户看到
- 将东西包装在一起,然后以新的完整形式呈现出来
- 例如,两种或多种化学药品组成一个胶囊
- 将方法和属性一起包装到一个单元中,单元以类的形式实现
- 封装的目的
- 隐藏类的实现细节
- 让使用者只能通过事先定制好的方法来访问数据,可以方便地加入控制逻辑,限制对属性的不合理操作
- 便于修改,增强代码的可维护性
- 可进行数据检查
② 访问权限修饰符
- 用来控制类的成员和类的使用范围
- 类成员的访问权限修饰符:private、default、protected、public
- 类的访问权限修饰符:public、default
4. 方法的覆盖
① 方法的覆盖 (override)
- 重写 (rewrite)
- 对从父类中继承来的方法进行改造
- 在子类继承父类时发生
② 方法覆盖的规则
- 在子类中的覆盖方法与父类中被覆盖的方法应具有
- 相同的方法名
- 相同的参数列表 (参数数量、参数类型、参数顺序都要相同)
- 相同的返回值类型
- 子类覆盖方法的访问权限要不小于父类中被覆盖方法的访问权限
5. 引用类型的转换
① 上溯造型
- 引用数据类型的转换(对象造型)
- 向上转型 (Upcasting) — 子类转换为父类,自动转换
- 前提 — 具有继承或实现关系
- 向上转换损失了子类新扩展的属性和方法,仅可以使用从父类中继承的属性和方法
- 向上转型 (Upcasting) — 子类转换为父类,自动转换
② 下溯造型
- 引用数据类型的转换
- 向下转型 (Downcasting):强制转换
- 将父类对象显示的转换成子类类型
- 向下转型 (Downcasting):强制转换
③ instanceof 运算符
- instanceof 运算符
- 判断一个类是否实现了某个接口:
对象 instanceof 接口
- 判断一个实例对象是否属于一个类:
对象 instanceof 类
- 它的返回值是boolean型的
- 判断一个类是否实现了某个接口:
6. 多态
① 多态
- 简单来说,多态是具有表现多种形态的能力的特征
- 同一个实现接口,使用不同的实例而执行不同操作
- 多态 (动态绑定、Polymorphism)
- 不同的对象对同一行为作出的不同响应
- 多态存在的三个必要条件
- 要有继承,或实现
- 要有重写
- 父类引用指向子类对象
一旦满足以上3个条件,当调用父类中被重写的方法后,运行时创建的是哪个子类的对象,就调用该子类中重写的那个方法
- 在执行期间 (而非编译期间) 判断所引用对象的实际类型,根据其实际类型调用相应的方法
- 多态的优点
- 简化代码
- 改善代码的组织性和可读性
- 易于扩展
7. 抽象类
① 抽象类
- 抽象类
- 抽象类是抽象方法和非抽象方法的集合
[访问权限修饰符] abstract class 类名 {……}
- 特殊情况
- 全部是抽象方法
- 全部为非抽象方法
- 抽象类是抽象方法和非抽象方法的集合
② 抽象方法
- 只有方法声明,没有方法实现的方法
[访问权限修饰符] abstract 返回值类型 抽象方法名 (参数列表) ;
③ 抽象类的规则
- 抽象类
- 注意:
- 抽象类不能被实例化;
- 其包含的抽象方法必须在其子类中被实现,否则该子类只能声明为 abstract;
- 抽象方法不能为 static;
- 在下列情况下,一个类必须声明为抽象类:
- 当一个类的一个或多个方法是抽象方法时;
- 当类是一个抽象类的子类,并且没有实现父类的所有抽象方法,即只实现部分;
- 当一个类实现一个接口,并且不能为全部抽象方法都提供实现时;
- 注意:
8. 接口
① 接口 (interface)
- 接口的声明
interface Runnable { public abstract void run(); }
- 接口中只包含常量和抽象方法,而没有变量和方法的实现
[访问权限修饰符] interface 接口名 {接口的成员}
- 接口的成员:
- 常量(字段)
- 抽象方法
- 接口中只包含常量和抽象方法,而没有变量和方法的实现
- 注意:
- 接口不是一个类,没有构造器,不能被实例化
- 接口使用 interface 关键字来定义,而不是 class
- 接口默认:
- 常量:
public static final
- 抽象方法:
public abstract
- 常量:
- 扩展接口 (接口的继承)
- 接口的意义
- 接口可以实现多继承
- 用接口可以实现混合类型 (主类型,副类型),java 中可以通过接口分出主次类型
- 主类型使用继承,副类型,使用接口实现
- 接口可以使方法的定义和实现相分离,降低模块间或系统间的耦合性
- 针对接口编程可以屏蔽不同实现间的差异,看到的只是实现好的功能
- 接口可以实现多继承
② 接口和类的关系
- 类实现接口 — implements
- 为了使用一个接口,你要编写实现接口的类
- 如果一个类要实现一个接口,那么这个类就必须实现接口中所有抽象方法。否则这个类只能声明为抽象类
- 多个无关的类可以实现一个接口,一个类可以实现多个无关的接口
- 一个类可以在继承一个父类的同时,实现一个或多个接口
- 类的单继承与多实现
- 类实现接口
- 示例:
- 有一个Student类
- 该类继承了Person类,并实现了Consumer接口
- 该类具有String类型的属性school
- 并有一个study方法,在该方法中,系统可打印出学生在那所学校学习
- 并创建一个测试方法,测试Student类
③ 接口与抽象类的区别
- 示例:
- 接口不能含有任何非抽象方法,而抽象类可以
- 类可以实现多个接口,但只能有一个父类
- 接口不是类分级结构的一部分,没有联系的类可以实现相同的接口
9. final关键字
final 关键字
- final 可以修饰的元素
- 类:不能被继承
- 变量(属性和局部变量):不能被重新赋值
- 在声明时赋值,或在构造器中赋值
- 系统不会对 final 属性默认的赋初始值
- 方法:不能在子类中被覆盖,即不能修改
10. 内部类
① 内部类
- 内部类 (嵌套类)
- 内部类就是定义在另一个类内部的类
- 内部类对于同一包中的其它类来说,内部类能够隐藏起来
- 注意
- 内部类可以访问其外部类中所有的属性和方法
- 无需创建外部类的对象,即可从内部类访问外部类的变量和方法
- 必须创建内部类的对象,否则无法从外部类访问内部类的变量和方法
- 如果内部类中有和外部类同名的变量或方法,则内部类的变量和方法将获得比外部类的变量和方法更高的优先级
- 不能定义 static 变量
- 类中定义的内部类
- 普通类的访问权限修饰符
- default
- public
- 内部类的访问权限修饰符
- default
- public
- protected
- private
- 普通类的访问权限修饰符
- 内部类的访问
- 在 Outer 内访问 Inner,只需如下:
Inner in = new Inner();
- 在Outer外访问Inner,必须如下:
Outer o = new Outer(); //实例化外部类
Outer.Inner oi = o.new Inner(); //实例化内部类
- 在 Outer 内访问 Inner,只需如下:
② 静态内部类
- 用static标识的内部类为静态内部类
- 静态内部类作为外部类的静态成员,不能访问外部类非静态成员
- 非静态内部类只能定义非静态成员,而静态内部类可以定义静态成员和非静态成员
- 使用
Outer.Inner in = new Outer.Inner()
方式实例化静态内部类 - 非静态内部类不可以使用上面的方式实例化
③ 局部内部类
- 局部内部类
- 在一个类的方法体中或程序块内定义的内部类
- 示例:在方法定义的内部类中只能访问方法中的 final 类型的局部变量
- 在一个类的方法体中或程序块内定义的内部类
public class Outer2 {
public int a = 1;
private int b = 2;
public void method(final int c) {
int d = 3;
final int e = 2;
class Inner {
private void iMethod(int e) {
//System.out.println(e);
}
}
}
}
小结
- 类的继承:子类的构造器
- Java 中的包和访问修饰符
- 方法的覆盖
- 引用数据类型的转换:向下转型、向上转型
- 多态:特征、动态绑定
- 抽象类和接口:定义、抽象方法、区别
- Final关键字
- 内部类
加油基础知识快学完了, 我觉得这篇相对于前边几篇来说格式更好了