1代码块
概念
分类
2继承于组合
概念
用法
3枚举
enum
概念
底层代码
用法
4抽象类
分类
使用规则
5接口
Interface
能够使用的方法
使用规则
6内部类
分类
加载是规则
7匿名内部类
用法
面向对象-抽象与接口
1. 课程介绍
Ø 1.代码块(了解)
Ø 2.继承与组合关系[看懂代码]
Ø 3.枚举(掌握:用的比较少)
Ø 4.抽象类(掌握)[掌握语法,切忌过分在乎用途]
Ø 5.接口(掌握)
Ø 6.内部类(了解)
回顾:面向对象的编程思想 : 面向对象的语法[重点掌握语法]
类[模板]和对象[复印件具体的东西]
代码 类--对象
java代码希望将现实中对象与对象的关系在计算机系统得以体现,从而构建计算机系统
汽车开发示例:具体的发动机[对象] 具体的轮胎[对象]: 用对象构建了汽车
软件系统: 面向对象:用对象
保持:执行流程 面向对象的编程思想
2. 代码块[了解]
2.1 什么是代码块
1. 可以看成是一块代码,一般都是有 { };括起来
2. 看到{} 应该想到作用域问题;
3. 也就是代码的访问范围:
4. 比如:这个j在if { }结构外面是无法访问的
class Test {
public static void main(String[] args) {
int i = 10;
if(i>=100){
int j = 100;
}
System.out.println(j);
}
}
2.2 分类-局部代码块[普通代码块]
1. 概念:一般由大括号 { } 括起来,写在方法体中的,代码块就是局部代码块
//测试类
class Test {
public static void main(String[] args) {
System.out.println(123456);
{
System.out.println(654321);
}
System.out.println(666666);
}
}
---------- Java ----------
123456
654321
666666
输出完成 (耗时 0 秒) - 正常终止
2. 如上代码都是按照顺序在执行
3. 一般的在方法里面直接写{} 没有多大实际意义,结合 if for来写才有意义
2.3 分类-构造代码块
1. 构造代码块:写在类结构体中的代码块,没有static修饰;
2. 编译完毕之后会在每一个构造方法里面复制一份;
3. 创建一个对象时[调用一次构造方法]就会执行一次构造代码块里面的代码
4. 可以给对象的实例字段初始化值[其实用得非常的少]
5. //测试类源文件
class Test {
final int i;
public static void main(String[] args) {
}
{
i = 10;
System.out.println(10);
}
Test(){
}
Test(int i){
}
}
6. 编译之后的文件
7. 测试
public static void main(String[] args) {
new Test();
new Test(1);
}
---------- Java ----------
10
10
输出完成 (耗时 0 秒) - 正常终止
2.4 分类-静态代码块
1. 直接写在类的结构体中,有static修饰的代码块;
2. 在类加载的时候执行和创建对象没有关系;
3. 优先于主方法执行
4. 作用:可以在类加载的时候做已写初始化的操纵(在就业班前期,JDBC(java去操作数据库)的)
//测试类
class Test {
public static void main(String[] args) {
System.out.println("主方法");
}
static {
System.out.println("静态代码块");
}
}
---------- Java ----------
静态代码块
主方法
输出完成 (耗时 0 秒) - 正常终止
2.5小结
1. 局部代码块
2. 构造代码块
3. 静态代码块
3. 继承与组合关系(了解-看懂代码就OK)
1. 组合是(has-a) 小悦悦有一个女朋友 关系,而继承则是(is-a) 人是一个动物 关系;
2. 组合关系在运行期决定,而继承关系在编译期就已经决定了。
3. 组合是在组合类和被包含类之间的一种松耦合关系,而继承则是父类和子类之间的一种紧耦合关系。
4. 当选择使用组合关系时,在组合类中包含了外部类的对象,组合类可以调用外部类必须的方法,而使用继承关系时,父类的所有方法和变量都被子类无条件继承,子类不能选择。
3.1什么是组合
1. 设计一个Student类,用其他类型作为Student类的字段,来描述Student类的静态属性,此时就是组合关系
2. class Student{//描述学生这一类的事物
String name;//用了另外一个类,描述学生的静态属性
}
3. String :描述了字符串的这一类事务
3.2 组合关系设计示例
1. 示意图:需求:设计一个手机类,存在手机卡:手机类可以查询手机号码
2. Card类表示手机卡:Card是一种数据类型
class Card{
String phoneNum;
Card(String phoneNum){
this.PhoneNum = PhoneNum;
}
public String getPhoneNum(){
return phoneNum;
}
}
3. 手机CellPhone:Card类型作为CellPhone的一个字段:描述CellPhone的静态属性手机卡
class CellPhone{
Card card;
CellPhone(Card card){
this.card = card;
}
public void showPhoneNum(){
String num = this.card.getPhoneNum();
System.out.println("您的靓号是:"+num);
}
}
4. 测试组合关系的使用:
//测试类
class Test {
public static void main(String[] args) {
Card card = new Card("15982889885");
CellPhone cphone = new CellPhone(card);
cphone.showPhoneNum();
}
}
5. JMV堆栈内存图示意分析:
3.3小结
4. 枚举(掌握)
4.1 枚举的引入:
1. 枚举:java类比较类似的结构:
2. 核心解决的问题:在java中,有一种数据类型,只存在固定的几个值
3. 什么是一种数据类型只存在固定的几个值
4. 例如 :String str = "1" "5" "就" ...... 每一个字符串都是String 类型的一个值:String 只有固定的几个值嘛?
a) 学习过类型哪些之后固定的几个值: boolean 单例模式
5. 设计一个人类,性别字段应该只有男女,所以该字段应该是只有固定的两个值
6. 设计思路分析
a) 思路分析:String ? int ? boolean ?都不好
b) 自己设计一个Sex类就是一个数据类型,一个对象就是一个值:
c) 所以只要对象创建的个数是固定的不变的:自己设计的类型的值就是固定的
d) 单利模式变多利模式【特殊写法看懂】
7. Sex类设计实现版本1
a) 构造方法私有化
b) public static final修饰,public 全局可以防范,static类名.字段名访问,final修饰不能修改
class Sex{
private Sex(){};
public final static Sex MAN = new Sex();
public final static Sex WOMAN = new Sex();
}
8. Sex类设计实现版本1测试
//测试类
class Test {
public static void main(String[] args) {
Sex man1 = Sex.MAN;
Sex man2 = Sex.MAN;
System.out.println(man1);
System.out.println(man2);
Sex woman1 = Sex.WOMAN;
Sex woman2 = Sex.WOMAN;
System.out.println(woman1);
System.out.println(woman2);
}
}
---------- Java ----------
Sex@15db9742
Sex@15db9742
Sex@6d06d69c
Sex@6d06d69c
输出完成 (耗时 0 秒) - 正常终止
结果:确保了:值固定个数,但是打印结果为地址值,不够直观
9. 方案2:解决方法1打印不够直观
1) 给每一个Sex对象里面内置一个String字段,用来存放保存性别的中文描述;
2) 在创建对象的时候,把中文写进去,toString里面返回对象中的中文描述;
class Sex{
String name;//描述性别值的一个字段
private Sex(){};//
public final static Sex MAN = new Sex("男");
public final static Sex WOMAN = new Sex("女汉字");
Sex(String name){
this.name = name;
}
//打印对象描述覆写toString方法
public String toString(){
return this.name;
}
}
4.2 什么是枚举
1. 枚举看成是 一个和 类 非常类似的新结构;
2. 枚举的出现解决了问题: 很轻松设计一种类型,让它的值只有固定个数,用于像性别这样的数据
4.3 枚举的使用场景
1. 性别, 星期,季节,VIP等级,段位。。。。
4.4 枚举的基本语法
1. 声明语法:
enum 枚举类名字{
字段
方法
构造方法 - 枚举中的构造方法默认都是private修饰,不能够是public
}
2. 一般枚举类型也是写在一个Java文件中,编译完毕也会生成字节码文件
3. 每一个自定义的枚举类型都(隐式的)拓展至 Enum 类,因此我们的枚举对象可以调用到Enum中的方法的(看API )
4. 自己百度测试switch使用枚举 以及回顾switch相关的语法
4.5 枚举示例代码及拓展
1. 示例代码: 设计一个性别的枚举类型
enum Sex{
男,女
}
2. 上面代码中 男 女 就是Sex类型的两个对象
//测试类
class Test {
public static void main(String[] args) {
System.out.println(Sex.男);
System.out.println(Sex.女汉子);
}
}
---------- Java ----------
男 为什么输出的是男 女汉子,枚举拓展在说明
女汉子
输出完成 (耗时 0 秒) - 正常终止
3. 分析: 其实上面的写法是不推荐的(其中的对象字段不应该使用中文),应该这样写:【常见的写法】
enum Sex{
MAN,WOMAN
}
4. 拓展: (希望打印上面的对象的时候打印出来是中文)
1) 在每一个枚举对象中内置一个String类型的字段保存中文描述;
2) 在创建每一个枚举对象的时候给中文描述字段赋值
3) 覆写toString,返回当前枚举对象的中文描述
enum Sex{
MAN("男"),WOMAN("纯爷们");
String name;//为了跟枚举常量添加中文描述
Sex(String name){//声明构造方法初始化枚举常量的值
this.name = name;
}
@Override
public String toString(){
return this.name;
}
}
4.6 枚举拓展自Object
1. 枚举拓展至Enum类,但是继承关系不能显示的写出来
2. 枚举里面toString方法 从哪里来?从Object类来,那枚举和Object有关系吗?
3. Enum类是Object的子类
java.lang.Enum<E>
这是所有 Java 语言枚举类型的公共基本类。
4.7小结
5. 抽象(掌握)
5.1抽象类的引入
1. 如上示例提出的问题
a) 父类中没必要写任何的功能实现,完全不需要方法结构体的存在
b) 如果其他类继承了该方法,应该提示必须覆写,功能重新实现
2. 解决办法:抽象
3. 什么是抽象:分类两大块抽象类,抽象方法,
a) abstract修饰的类就是抽象类
b) abstract修饰的方法就是抽象方法
5.2抽象类
1. 抽象类是一个跟类一样的结构,抽象类本质也是一个类
2. 类中有的成员,抽象类都可以有(字段 方法 构造方法),此外抽象类中还可以有抽象方法
abstract class Graph{
int i = 10;//抽象类中定义字段
public void add(){//抽象类中定义普通方法
}
Graph(){//抽象类中定义构造方法
}
}
3. 抽象类不能够实例化
//测试类
class Test {
public static void main(String[] args) {
new Graph();
}
}
Test.java:4: 错误: Graph是抽象的; 无法实例化
new Griph();
^
1 个错误
输出完成 (耗时 0 秒) - 正常终止
4. 抽象类的使用场景: 一般作为父类(基类,模板类),模板方法模式
5. 支持多多态写法
5.3抽象方法
1. 使用abstract 修饰的方法就是抽象方法没有方法主体;
2. 抽象方法必须存于抽象类中[接口也可以],不能够放在普通类中
3. 抽象类的子类
a) 非抽象类必须覆写父类中的所有的抽象方法,
b) 抽象类不用覆写父类中的抽象方法
5.4 抽象应用示例[会写]
class Test{
public static void main(String[] args) {
Graph g1 = new Circle();
}
Graph getP(){
return new Circle();//多态返回值形式,方法返回的是抽象类类型:所以方法内部,必然返回的是抽象类的子类对象
}
}
abstract class Graph{
abstract int getLength();//
}
class Circle extends Graph{
double r;//半径
int getLength(){
return 0;
}
}
5.5小结
1. 为什么需要抽象:因为提取的公共的模板方法,根本没必要做任何实现,并且应该提示继承的类必须覆写
2. 什么是抽象:
(1) abstract 修饰的类及方法 : 不创建对象
3. 抽象类:abstract 修饰的一个类就是抽象类,字段普通方法,构造方法,都可以有,但是可以有抽象方法
4. 抽象方法:abstract
(1) 修饰的一个方法就是抽象方法,只能存在于抽象类及接口中 没有方法体,
(2) 子类非抽象类,必须覆写抽象方法
5. 抽象的作用: 模板类,基类,根类:主要作为公共的模板,提取公共的属性放到里面,让其他的子类继承,自己不能创建对象
6. 接口(掌握)
6.1 接口的引入
1. 同学们有没有听说过接口
接口以前已经提到过,比如 引用类型 包括 类 接口 数组,或者抽象方法可以存在抽象类或者接口里面;
提到接口 ,会想到啥?
2. 现实生活中 USB接口
a) 插入充电宝:在充电宝端实现了充电功能
b) 插入手机:在手机端实现了数据传入,及充电功能
c) 插入键盘:在键盘端实现了键盘输入
d) 插入鼠标:在鼠标端实现了鼠标功能
3. USB接口的体会:插入不同的设备实现不同的功能
6.2程序(软件开发)中的接口
1. 对于接口有两种理解
1) 软件与软件之间数据交互的接口【面试一般问的这个接口】
2) java中的接口
2. Java中的接口:是一个跟类很相似的结构
3. 接口的语法:
interface 接口名{
}
4. 一般写在一个独立的Java文件中,编译完毕之后也会生成独立的字节码文件
5. 接口内部成员参考类
a) 可以有字段:默认public static final 修饰的全局常量
b) 方法全部都是抽象方法【没有 static final修饰 因为修饰的不能覆写,抽象方法需要覆写才有意义 】
c) 构造方法没有
interface USB{
int i = 10;//默认public static final 修饰
void add();//默认public abstract 修饰
}
6.3接口如何使用
1. 从结构上来看,接口中有全局常量和抽象方法
a) 全局常量 : 接口名.常量名 直接调用
b) 抽象方法 : 类实现接口,覆写接口中的抽象方法
c) 子接口继承父接口,拓展接口
d) 接口也是支持多态的写法的
6.4类实现接口
1. 定义一个类来实现(implements)接口语法
interface A{}
class B implements A{
1) B非抽象类,必须全部覆写接口中的抽象方法
}
2. A接口类型相当于是B类型的父类:支持多态写法
A a1 = new B(); // 多态的写法
a1.eat(); // 多态方法调用
3. 一个类其实可以实现多个接口,需要覆写所有接口中的抽象方法
4. 一个类可以在继承一个类的同时实现多个接口,但是继承的代码必须写实现前面
6.5接口-接口 拓展(extends 继承)
1. 接口与接口之间支持允许继承
2. 一个接口可以继承多个接口
6.6小结
1. 接口的引入介绍
(1) 以后面试用到的接口
(2) java中的接口
2. 接口的基本语法
3. 类实现接口
4. 接口与接口
5. 多态写法
7. 内部类(了解)
7.1什么是内部类
1. 内部类:把一个类定义在另外一个类的内部,嵌套类,宿主类。[外部类的一个成员]
2. 内部类编译完毕也会生成独立的字节码文件: 外部类名$内部类名.class
3. 本质也是一个类!
7.2真实的使用场景
1. 一般来说,类都应该是独立的写在一个自己的Java文件中;
2. 本质效果相当于是一种封装;
3. 示例: 例如手机类,手机卡类存在于同一个项目中,如果说手机卡类的存在仅仅在手机类中有意义(只有手机类的内部会用到手机卡),为了更好的封装,把手机卡类整体移动到手机类中去,其它所有代码都不变。
7.3语法层面验证(实用性不大)
1. 内部类编译完毕也会生成独立的字节码文件,外部类名$内部类名.class;
2. 语法上面再外部类的外部来尝试访问内部类以及内部类中的成员如下的效果,但实际开发中一般不这样写
class TestInnerClass {
/*
内部类:类中的一个类叫做内部类!本质还是一个类而已
没啥可学的!本质已经学完类的语法了,所以内部类的语法基本类似,当做一个类来就行了
内部类有啥用:
在适当的时候,可以有更好的封装:例如手机卡:
*/
public static void main(String[] args) {
//Inner in = new Inner();//内部类,如此使用创建对象不行
//①非静态内部类创建对象,本质是类中的成员,想要类中成员来创建对象:[得通过外部类的对象访问]
Outer.Inner inner = new Outer().new Inner();
System.out.println(inner);
//②静态内部类创建对象,本质是类中的成员,想要类中成员来创建对象:[得通过外部类访问]
Outer.Inner1 inner1 = new Outer.Inner1();
System.out.println(inner1);
/*
③非静态内部类中的方法的方法
1.静态的方法:不能声明静态方法
2.非静态的方法:通过内部类的对象访问
*/
inner.run();
/*
④静态内部类中的方法的方法
1.静态的方法:
2.非静态的方法
*/
Outer.Inner1.eat();
inner1.run();
}
}
class Outer{
class Inner{//非静态的内部类
//static void eat(){//不能声明静态方法
// System.out.println("非静态的内部类的静态方法");
//}
void run(){//不能声明静态方法
System.out.println("非静态的内部类的非静态方法");
}
}
static class Inner1{//静态的内部类
static void eat(){//不能声明静态方法
System.out.println("静态的内部类的静态方法");
}
void run(){//不能声明静态方法
System.out.println("静态的内部类的非静态方法");
}
}
}
7.4 匿名内部类(匿名内部类对象的创建)
7.4小结
8. 课程总结
1.1. 重点
1. 枚举
2. 抽象
3. 接口
1.2. 难点
1. 继承与组合:代码逻辑较多,需要细致分析读懂!
1.3. 如何掌握?
1. 勤加练习...
2. 学会看说明手册
1.4. 排错技巧(技巧)
9. 课后练习【100分钟】
第一题:什么是类和对象,请举例说明 100%
类:泛指一相同属性和方法的集合
对象:具体个体
class A{}
A a=new A();
第二题:如何设计一个类,语法是什么,类中有哪些成员(字段,方法,构造方法),举例说明 100%
用class标识,一定会有构造方法
第三题:构造方法是什么? 有什么作用?构造方法的语法是什么?说明并举例 100%
第四题:什么是JavaBean,理解后写出一个标准的 100%
第五题:Java中继承有何意义?100%
第八题:方法覆写和重载有什么区别,并举例说明 100%
第九题:你理解的Java中多态部分的核心代码是什么,举例说明
第十题:你理解的static super this 的用法 100%
第十一题:final修饰符有什么用?基本用法和注意事项 100%
第十二题:什么时候可能会用到内部类--》比如 手机类 有一个手机卡 可以内部类(100%)
第十三题:枚举类型的存在解决了什么问题 100%
第十四题:单例模式的书写流程 100%
第十五题:熟练写出(并记住)抽象类和接口中的语法 100%
第十六题:你理解的接口和抽象类的区别(可以从语法结构和应用场景进行描述)
10. 面试题
解释单例模式,写一个单利模式
11. 扩展知识或课外阅读推荐(可选)
1.5. 扩展知识
1.6. 课外阅读
12. 每日一练【15】