#博学谷IT学习技术支持#
5 面向对象进阶
5-1 分类和static
02-分类思想
如果将所有的类文件都放在同一个包下,不利于管理和后期维护,所以,对于不同功能的类文件,可以放在不同的包下进 行管理
03-包的概述和定义
- 包
本质上就是文件夹
- 创建包
多级包之间使用 " . " 进行分割 多级包的定义规范:公司的网站地址翻转(去掉www) 比如:it的网站 址为www.it.com 后期我们所定义的包的结构就是:com.it.其他的包名
- 包的命名规则
字母都是小写
04-包的注意事项
- package语句必须是程序的第一条可执行的代码
- package语句在一个java文件中只能有一个
- 如果没有package,默认表示无包名
04-类访问
- 同一个包下的访问
- 不需要导包,直接使用即可
- 不同包下的访问
- import 导包后访问
- 通过全类名(包名 + 类名)访问
- 注意:import 、package 、class 三个关键字的摆放位置存在顺序关系
- package 必须是程序的第一条可执行的代码
- import 需要写在 package 下面
- class 需要在 import 下面
12-static关键字特点
static 关键字是静态的意思,是Java中的一个修饰符,可以修饰成员方法,成员变量
- 被类的所有对象共享
- 随着类的加载而加载,优先于对象存在
- 可以通过类名调用 也可以通过对象名调用
13-static注意事项
- 静态方法只能访问静态的成员
- 非静态方法可以访问静态的成员,也可以访问非静态的成员
- 静态方法中是没有this关键字
5-3 继承
01-继承入门
继承是面向对象三大特征之一,可以使得子类具有父类的非私有属性和方法
格式: 格式:class 子类 extends 父类 { } 举例:class Dog extends Animal { }
02-继承的好处和弊端
继承好处
- 提高了代码的复用性
- 提高了代码的维护性
继承弊端
- 继承是入侵性的
- 降低了代码的灵活性(子类拥有所有父类的属性和方法)
- 类的耦合性增强(代码之间的关联性增强)
继承的应用场景:
使用继承,需要考虑类与类之间是否存在is..a的关系,不能盲目使用继承
03-继承的特点
Java中类只支持单继承,不支持多继承
04-继承中成员变量的访问特点
在子类方法中访问一个变量,采用的是就近原则。
-
子类局部范围找
-
子类成员范围找
-
父类成员范围找
-
如果都没有就报错(不考虑父类的父类…)
05-this和super
this&super关键字:
this:代表本类对象的引用
super:代表父类存储空间的标识(可以理解为父类对象引用)
访问成员的格式:
| 关键字 | 访问成员变量 | 访问成员方法 | 访问造方法 |
|---|---|---|---|
| this | this.成员变量 | this.成员方法 | this(…) |
| super | super.成员变量 | super.成员方法 | super(…) |
06 -继承中成员方法的访问特点
通过子类对象访问一个方法
-
子类成员范围找
-
父类成员范围找
-
如果都没有就报错
07-方法重写概述和应用场景
1、方法重写概念
子类出现了和父类中一模一样的方法声明(方法名一样,参数列表也必须一样)
2、方法重写的应用场景
当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样,即沿袭了 父类的功能,又定义了子类特有的内容
3、Override注解
用来检测当前的方法,是否是重写的方法,起到【校验】的作用
08-方法重写的注意事项
-
私有方法不能被重写(父类私有成员子类是不能继承的)
-
子类方法访问权限不能更低(public > 默认 > 私有)
-
静态方法不能被重写,如果子类也有相同的方法,并不是重写的父类的方法
09-权限修饰符
10-继承中构造方法的访问特点
注意:子类中所有的构造方法默认都会访问父类中无参的构造方法
子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化, 原因在于,每一个子类构造方法的第一条语句默认都是:super()
注意: this(…)super(…) 必须放在构造方法的第一行有效语句,并且二者不能共存
11-构造方法的访问特点-父类没有空参构造方法
问题:如果父类中没有无参构造方法,只有带参构造方法,该怎么办呢?
-
通过使用super关键字去显示的调用父类的带参构造方法
-
子类通过this去调用本类的其他构造方法,本类其他构造方法再通过super去手动调用父类的带参的构造方法
14-抽象类
在Java中,一个没有方法体的方法应该定义为抽象方法,
而类中如果有抽象方法,该类必须定义为抽象类
抽象类的特点
- 抽象类和抽象方法必须使用 abstract 关键字修饰
//抽象类的定义
public abstract class 类名 {
}
//抽象方法的定义
public abstract void eat();
15-抽象类的注意事项
- 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
- 抽象类可以有构造方法
- 抽象类的子类,要么重写抽象类中的所有抽象方法、要么是抽象类
16-模板设计模式
设计模式(Design pattern )
模板设计模式
17-final关键字
final代表最终的意思,可以修饰成员方法,成员变量,类
final修饰类、方法、变量的效果 :
-
fianl修饰类:该类不能被继承(不能有子类,但是可以有父类)
-
final修饰方法:该方法不能被重写
-
final修饰变量:表明该变量是一个常量,不能再次赋值
- 变量是基本类型,不能改变的是值
- 变量是引用类型,不能改变的是地址值,但地址里面的内容是可以改变的
-
修饰类成员变量:直接定义或者在构造方法赋值
19-代码块
在Java中,使用 { } 括起来的代码被称为代码块
局部代码块
位置: 方法中定义
作用: 限定变量的生命周期,及早释放,提高内存利用率
构造代码块
位置: 类中方法外定义
特点: 每次构造方法执行的时,都会执行该代码块中的代码,并且在构造方法执行前执行
作用: 将多个构造方法中相同的代码,抽取到构造代码块中,提高代码的复用性
静态代码块
位置: 类中方法外定义
特点: 需要通过static关键字修饰,随着类的加载而加载,并且只执行一次
作用: 在类加载的时候做一些数据初始化的操作
5-5 接口
03-接口的介绍
接口就是一种公共的规范标准,当一个类中所有方法都是抽象方法时,就可以定义为接口。
接口也是一种数据类型,它比抽象类还要抽象
Java中接口存在的两个意义
-
用来定义规范
-
用来做功能的拓展
04-接口的定义和特点
接口用关键字interface修饰
public interface 接口名 {}
类实现接口用implements表示
public class 类名 implements 接口名 {}
-
接口不能实例化
- 可以创建接口的实现类对象使用
-
接口的子类
- 要么重写接口中的所有抽象方法
- 要么子类也是抽象类
-
可以多实现
public class 类名 implements 接口名1, 接口名2 {}
05-接口中的成员特点
-
成员变量
- 只能是常量 默认修饰符:public static final
-
构造方法
- 没有,因为接口主要是扩展功能的,而没有具体存在
-
成员方法
- 只能是抽象方法 默认修饰符:public abstract
- 关于接口中的方法,JDK8和JDK9中有一些新特性
06-JDK8版本中成员的特点-默认方法
允许接口中定义非抽象方法,但是要使用关键字default修饰,这些方法就是默认方法
作用:解决接口升级问题
接口中默认方法的定义格式:
格式:public default 返回值类型 方法名 (参数列表) { }
范例:public default void show () {}
注意事项:
默认方法不是抽象方法,所以不强制重写,也可以被重写
public可以省略
如果实现多个接口,具有相同方法声明,子类就必须重写方法
07-JDK8版本中接口成员的特点-静态方法
格式 : public static 返回值类型 方法名(参数列表) { }
范例:public static void show () {}
注意事项
- 静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
- public可以省略
08-JDK9版本中接口成员的特点-私有方法
Java 9中新增了带方法体的私有方法
定义格式
- private 返回值类型 方法名(参数列表) { }
- private void show() { }
- private static 返回值类型 方法名(参数列表) { }
- private static void method() { }
09-类和接口的关系
- 类与类的关系
继承关系,只能单继承,但是可以多层继承
- 类与接口的关系
实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
- 接口与接口的关系
继承关系,可以单继承,也可以多继承
5-6 多态与内部类
12-多态
什么是多态
- 同一个对象,在不同时刻表现出来的不同形态
多态的前提
- 要有继承或实现关系
- 要有方法的重写
- 要有父类引用指向子类对象
13-多态中成员访问的特点
成员访问特点
-
成员变量
- 编译看父类,运行看父类
-
成员方法
- 编译看父类,运行看子类
14-多态的好处和弊端
好处: 提高程序的扩展性。定义方法时候,使用父类型作为参数,在使用的时候,使用具体的子类型参与操作
弊端: 不能使用子类的特有成员
15-多态中的转型
向上转型
父类引用指向子类对象就是向上转型
向下转型
格式:子类型 对象名 = (子类型)父类引用
16-多态中转型存在的风险和解决方案
如果被转的引用类型变量,对应的实际类型和目标类型不是同一种类型,那么在转换的时候就会出现 ClassCastException
- 关键字 :instanceof
- 使用格式 :变量名 instanceof 类型
- 通俗的理解:判断关键字左边的变量,是否是右边的类型,返回boolean类型结果
18-内部类-成员内部类
在一个类中定义一个类。
举例:在一个类A的内部定义一个类B,类B就被称为内部类
/* 格式: class 外部类名{ 修饰符 class 内部类名{ } } */
class Outer {
public class Inn {
}
}
内部类的访问特点 :
- 内部类可以直接访问外部类的成员,包括私有
- 外部类要访问内部类的成员,必须创建对象
public class Outer {
private int num = 10;
public class Inner {
public void show() {
System.out.println(num);
}
}
public void method() {
Inner i = new Inner();
i.show();
}
}
19-私有成员内部类-静态成员内部类
-
成员内部类的定义位置
- 在类中方法,跟成员变量是一个位置
-
外界创建成员内部类格式
- 格式:外部类名.内部类名
- 对象名 = 外部类对象.内部类对象;
- 举例:Outer.Inner oi = new Outer().new Inner();
-
私有成员内部类
- 外部无法访问,方法内部创建内部类对象并调用。
- private class func() {}
-
静态成员内部类
- 静态成员内部类访问格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();
- 静态成员内部类中的静态方法:外部类名.内部类名.方法名();
20-局部内部类
局部内部类定义位置
- 局部内部类是在方法中定义的类
局部内部类方式方式
- 局部内部类,外界是无法直接使用,需要在方法内部创建对象并使用
- 该类可以直接访问外部类的成员,也可以访问方法内的局部变量
21-匿名内部类
-
匿名内部类的前提
- 存在一个类或者接口,这里的类可以是具体类也可以是抽象类
-
匿名内部类的格式
- 格式:new 类名 ( ) { 重写方法 }
- 举例:
new Inter(){
@Override public void method(){
}
}
-
匿名内部类的本质
- 本质:是一个继承了该类或者实现了该接口的子类匿名对象
- 将【继承\实现】【方法从写】【创建对象】三个步骤放在一步进行
-
匿名内部类的细节
- 匿名内部类可以通过多态的形式接受
Inter i = new Inter(){
@Override public void method(){
}
}
- 匿名内部类直接调用方法
new Inter(){
@Override public void method(){
System.out.println("我是匿名内部类");
}
}.method(); // 直接调用方法
22-匿名内部类的使用场景
interface Swimming { void swim(); }
public class TestSwimming {
public static void main(String[] args) {
goSwimming(new Swimming() {
@Override
public void swim() {
System.out.println("铁汁, 我们去游泳吧");
}
});
}
public static void goSwimming(Swimming swimming){
swimming.swim();
}
}
5-7 Lambda表达式
23-Lambda函数式编程思想
函数式编程思想概述
在数学中,函数就是有输入量、输出量的一套计算方案,也就是“拿数据做操作” 面向对象思想强调“必须通过对象的形式来做事情” 函数式思想则尽量忽略面向对象的复杂语法:“强调做什么,而不是以什么形式去做” 而Lambda表达式就是函数式思想的体现
24-Lambda表达式的格式说明和前提条件
格式说明
- 格式: (形式参数) -> {代码块}
- 形式参数:如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可
- ->:由英文中画线和大于符号组成,固定写法。代表指向动作
- 代码块:是我们具体要做的事情,也就是以前我们写的方法体内容 组成Lambda表达式的三要素: 形式参数,箭头,代码块
使用前提
- 有一个接口
- 接口中有且仅有一个抽象方法
28-Lambda的省略模式
省略的规则
- 参数类型可以省略。但是有多个参数的情况下,不能只省略一个
- 如果参数有且仅有一个,那么小括号可以省略
- 如果代码块的语句只有一条,可以省略大括号和分号,和return关键字
29-匿名内部类和Lambda表达式的区别
-
所需类型不同
- 匿名内部类:可以是接口,也可以是抽象类,还可以是具体类
- Lambda表达式:只能是接口
-
使用限制不同
- 如果接口中有且仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类
- 如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式
-
实现原理不同
- 匿名内部类:编译之后,产生一个单独的.class字节码文件
- Lambda表达式:编译之后,没有一个单独的.class字节码文件。对应的字节码会在运行的时候动态生成