类的五大成员
1. 属性 2.方法 3.构造器 4.代码块 5.内部类
class Outer { //外部类
private int num; //1.属性
public Outer(int num) { //2.构造器
this.num = num;
}
public void method() { //3.方法
System.out.println("成员方法");
}
{ //4.代码块
System.out.println("代码块...");
}
class Inner { //5.内部类
}
}
局部内部类
局部内部类的作用域:定义在成员方法中的类
格式
class Outer {
public void method() {
class Inner { // 局部内部类
}
}
}
注意事项
-
局部内部类不能添加访问修饰词,但可以添加 final修饰词,因为局部变量也能使用final修饰词
-
外部类和局部内部类的成员重名时,默认遵循就近原则【代码演示】
-
访问机制【代码演示】
局部内部类 --直接访问–> 外部类的成员(包括私有)
外部类的成员 --间接访问–> 局部类的成员(访问方式:创建对象,再访问)
外部其他类 --不能访问–> 局部类的成员
代码演示:局部内部类的访问机制
public class Demo {
public static void main(String[] args) {
Outer outer = new Outer();
outer.method();
}
}
class Outer {
int num1 = 20;
private int num2 = 40;
void method() {
class Inner {
int num1 = 30;
void method1() {
System.out.println(num1); // 运行结果:30
// (外部类和局部内部类的成员重名时,访问内部类的成员)
System.out.println(Outer.this.num1); // 运行结果:20
// (外部类和局部内部类的成员重名时,访问外部类的成员)
System.out.println(num2); // 运行结果:40
// (直接访问外部类的成员)
}
}
Inner inner = new Inner();
inner.method1();
// (访问内部类的成员)
}
}
匿名内部类
匿名内部类的作用域:定义在外部类的成员方法里面或代码块里面
格式
new 类或接口(参数列表) {
类体
}.方法名();
类型 对象名 = new 类或接口(参数列表) {
类体
};
对象名.方法名();
个人对两种看法
第一种,无论重写了几个方法,只能调用一个方法
第二种,重写了几个方法,可以通过对象名访问多个方法
代码演示:传统方案:先实现类再调用
public class Demo {
public static void main(String[] args) {
Animal animal = new Monkey();
animal.cry();
}
}
interface Animal {
void cry();
}
class Monkey implements Animal {
@Override
public void cry() {
System.out.println("哞哞~~");
}
}
代码演示:匿名内部类与接口
public class Demo {
public static void main(String[] args) {
// 使用匿名内部类:只调用一次
new Animal() {
@Override
public void cry() {
System.out.println("汪汪叫~~~");
}
}.cry();
}
}
interface Animal {
void cry();
}
代码演示:匿名内部类与抽象类
public class Demo {
public static void main(String[] args) {
new Animal() {
@Override
public void cry() {
System.out.println("汪汪叫~~~");
}
}.cry();
}
}
abstract class Animal {
abstract void cry();
}
代码演示:匿名内部类与类
public class Demo {
public static void main(String[] args) {
new Animal() {
@Override
public void cry() {
System.out.println("汪汪叫~~~");
}
}.cry();
}
}
class Animal {
void cry() {
System.out.println("动物在叫唤...");
}
}
注意事项
- 外部其他类不能访问匿名内部类【切记】
- 匿名内部类与外部类的成员重名时,优先就近原则,如果要访问外部类(外部名.this.成员)【代码演示】
- 匿名内部类可以直接访问外部类成员,包括私有的【代码演示】
代码演示:匿名内部类的访问机制
public class Demo {
public static void main(String[] args) {
Monkey monkey = new Monkey();
monkey.method();
}
}
abstract class Animal {
abstract public void cry();
}
class Monkey { // 外部类
private int num1 = 10;
void method() {
new Animal() { //匿名类
int num1 = 20;
@Override
public void cry() {
System.out.println(num1); // 访问匿名类中的成员
System.out.println(Monkey.this.num1); // 访问外部类的成员
}
}.cry();
}
}
代码演示:匿名内部类应用
1.有一个铃声接口 Bell,里面有个 ring 方法
2.有一个手机类 Cellphone,具有闹钟功能 alarmClock,参数是 Bell 类型
3.测试手机类的闹钟功能,通过匿名内部类(对象)作为参数,打印:懒猪起床了
public class Demo {
public static void main(String[] args) {
Cellphone cellphone = new Cellphone();
cellphone.alarmClock(new Bell() {
@Override
public void ring() {
System.out.println("懒猪起床了");
}
});
}
}
interface Bell {
void ring();
}
class Cellphone {
public void alarmClock(Bell bell) {
bell.ring();
}
}
成员内部类
成员内部类的作用域:定义在外部类的成员位置
格式
class Outer {
class Inner { //成员内部类
}
}
注意事项
- 可以添加任意访问修饰符,它是一个成员
- 访问机制【代码演示】
成员内部类 --直接访问–> 外部类的成员(包括私有)
外部类 --访问–> 成员内部类的成员
(外部类访问成员内部类的两种方式)
间接访问格式:创建一个外部类的成员方法,包含内部类的对象,通过外部类来访问成员变量,进而来访问成员内部类
直接访问格式:外部类.成员内部类 变量 = new 外部类().new 成员内部类();
代码演示:成员内部类的访问机制
public class Demo {
public static void main(String[] args) {
Outer outer = new Outer();
outer.method(); // (间接访问内部类的成员)
Outer.Inner in = new Outer().new Inner();
in.method1();
}
}
class Outer {
private int num1 = 10; //成员变量
void method() { //成员方法
Inner inner = new Inner();
inner.method1();
}
class Inner { //成员内部类
public void method1() {
System.out.println(num1); //直接访问外部成员变量
}
}
}
静态内部类
静态内部类的作用域:定义在外部类的成员,并且添加static关键字
格式
class Outer {
static class Inner { //静态内部类
}
}
注意事项
- 可以添加任意访问修饰符,因为它是一个成员
- 访问机制【代码演示】
静态内部类 --直接访问–> 外部类的静态成员
外部类 --间接访问–> 静态内部类(访问方式:创建对象,再访问)
外部其他类 --访问–> 静态内部类
代码演示:静态内部类的访问机制
public class Demo {
public static void main(String[] args) {
Outer outer = new Outer();
outer.method(); // (间接访问内部类的成员)
}
}
class Outer {
private static int num1 = 10;
public void method() {
Inner inner = new Inner();
inner.method1();
}
public static class Inner {
int num1 = 20;
public void method1() { // 外部类与静态内部类的属性重名
System.out.println(num1); // 访问静态内部类的属性
System.out.println(Outer.num1); // 访问外部类的属性
}
}
}