今日内容
final关键字
权限修饰符
内部类 [了解]
引用数据类型作为参数或者返回值类
final关键字
最终,不可以改变的意思,它可以修饰类、方法、成员变量和局部变量
final修饰类
final修饰的类不能被继承
注:没有子类,但是可以有父类,可以继承和重写父类的方法
final修饰的类其中的方法都不能被重写
面试题:
请说出JDK提供的API中常见的final类。
Math类、String类、Scanner类和System类
final修饰方法
final修饰的方法不能被重写
注:但是可以被继承
final修饰成员变量
final修饰的成员变量不能被重新赋值,变成了常量
final修饰的成员变量必须赋值,赋值两个时机:
(1)直接手动赋值
private final String name = "张三";
(2)通过构造方法赋值
// 没有手动赋值,就必须使用构造方法赋值
private final String name;
public Person() {
name = "关晓彤";
}
final修饰局部变量
final修饰的局部变量不能被重新赋值,变成了常量
基本数据类型的局部变量,不能改变的是值
// final修饰的基本数据类型的局部变量
final int num = 10;
// 错误,值不能改变
// num = 20;
引用数据类型的局部变量,不能改变的是地址值,但是其中存储的内容是可以改变的
// final修饰的引用数据类型的局部变量
final Student s = new Student("张三",20);
// 错误,地址值不能改变
// s = new Student("张三",21);
System.out.println(s.getName() +","+s.getAge());// 张三,20
// 正确,内容改变,但是地址值没有改变
s.setAge(21);
System.out.println(s.getName() +","+s.getAge());// 张三,21
总结:
(1)final修饰的类不能被继承
(2)final修饰的方法不能被重写
(3)final修饰的变量(成员或者局部变量)不能重新赋值
权限修饰符
可以修饰类、成员变量、成员方法、构造方法等,限制它们的访问范围(本类、本包、本模块)
4个:public > protected > 默认 > private
本类 本包 不同包子类 不同包其他类
public √ √ √ √
protected √ √ √ ×
默认 √ √ × ×
private √ × × ×
总结:
private修饰的只能在本类中访问,出了类不能访问
默认修饰的只能在本包中访问,出了包不能访问
protected在本包和不同包的子类中可以访问
public修饰的在整个模块中访问,出了模块不能访问
修饰符
权限修饰符:public protected 默认 private
其他修饰
静态修饰符:static
最终修饰符:final
抽象修饰符:abstract
修饰类
public 默认
final abstract
修饰成员变量
public protected 默认 private
static final
修饰局部变量
final
修饰成员方法
public protected 默认 private
static final abstract
修饰构造方法
public protected 默认 private
内部类
一个类中的组成部分:
成员变量(常量)
成员方法
构造方法
代码块(静态代码块、构造代码块)
成员内部类(内部接口、内部枚举)
注:一个类只能直接编写以上的内容,否则编译报错
在一个类的内部再定义一个类,内部定义的那个类就是内部类
分类:
(1)成员内部类
(2)局部内部类
(3)匿名内部类(特殊的局部内部类)
成员内部类
位置:类中方法外
格式:
修饰符 class 外部类类名{ // 外部类
修饰符 class 内部类类名{ // 成员内部类
}
}
特点:
内部类可以直接访问外部类的成员,即使是private修饰的
外部类想访问内部类的成员,不能直接访问,必须借助内部类的对象
不管是外部类还是内部类,都会生成.class文件,如果是成员内部类生成的文件名的格式:
外部类名$内部类名.class
Outer$Inner.class
使用
(1)间接使用
在外部类的方法中创建内部类的对象,再通过对象调用内部类的方法
在测试类中创建外部类的对象,再通过对象调用外部类的方法
(2)直接使用
在测试类中创建内部类的对象,再通过对象调用方法
内部类的对象创建的格式:
外部类名.内部类名 对象名 = new 外部类名().new 内部类名();
Outer.Inner oi = new Outer().new Inner();
Body.Heart bh = new Body().new Heart();
内部类的成员变量和外部类的成员变量同名,在内部类中访问外部类的同名成员变量:
外部类名.this.成员变量
成员内部类的修饰符
我们目前学习到的7种修饰符都可以使用
public protected 默认 private
static final abstract
局部内部类
位置:方法中
特点:
只能在其所定义的方法内部使用,而且必须先定义再使用
出了所定义的方法内部是不能使用的,即使在本类的其他方法中都不能使用
使用:
在其所定义的方法内部创建局部内部类的对象,然后再通过对象调用方法
编译之后的.class文件格式:
外部类名$编号内部类名.class
Outer$1Inner.class
局部内部类访问所在方法的局部变量时,局部变量必须使用final修饰
从JDK1.8开始,如果保证局部变量事实不改变(没有对其进行重新赋值),final关键字可以省略
匿名内部类(掌握)
本质:
是一个局部内部类,只不过它没有名字
应用场景:
当一个接口的实现类(父类的子类)只使用一次的情况下,为了简化操作
匿名对象:解决对象只使用一次的情况,是为了代码简化,不需要再使用变量接收
匿名内部类:解决类只使用一次的情况,是为了简化操作,不需要再创建类
格式:
接口名或者父类名 对象名 = new 接口名或者父类名(){
// 方法重写
};
new 接口名或者父类名(){
// 方法重写
}.重写的方法;
(1)由于匿名内部类没有名字,所以使用的时候只能直接创建其对象
(2)new 接口名或者父类名(),不是在创建接口的对象,也不是在创建父类的对象,
而是创建接口的实现类对象,或者父类的子类对象
(3)要使用匿名内部类必须有一个接口,或者有一个父类(普通类或者抽象类)
如果一个类作为方法的形式参数,调用方法传递的实参是该类的对象或者该类的子类对象
如果一个抽象类作为方法的形式参数,调用方法传递的实参只能是该类的子类对象
如果一个接口作为方法的形式参数,调用方法传递的实参只能是该接口的实现类对象
今日重点
(1)能说出final修饰的内容及其特点
(2)独立编写代码演示final修饰的内容及其特点
(3)能够说出4种权限修饰的权限范围
(4)独立编写代码演示4种权限修饰符的使用
(5)了解成员内部类和局部内部类 [可以不看]
(6)独立使用匿名内部类
(7)独立编写代码使用类作为另一个类的成员变量的类型 [难点]
英雄和武器
人和宠物
(8)了解接口作为另一个类的成员变量的类型 [难点]
(9)了解接口作为方法的参数列表和返回值类型 [难点]