1. 内部类
- 成员内部类、静态内部类 、局部内部类、匿名内部类
1.1. 成员内部类
- 成员内部类 定义位置: 外部类里里面 方法的外面 和成员变量的位置一样
- 创建内部类对象的格式 外部类名.内部类名 对象名 = new 外部类对象().new 内部类对象();
- 也就是说:创建内部类对象,但必须先创建外部类对象
1.1.1. 代码
-
类Outer中定义里一个内部类Inner,
-
内部类里面可以直接访问外部类的成员, , 包括私有成员,比如下面show方法中 访问了外部的变量name
public class DEmo01 {
public static void main(String[] args) {
//创建外部类的对象
Outer outer = new Outer();
//System.out.println(outer.age);
//外部类的对象来创建内部类的对象
outer.new Inner();
//创建内部类的对象
Outer.Inner inner = new Outer().new Inner();
//调用show方法
inner.show();
}
}
public class Outer {
private String name = "xiaoming";
int age = 20;
class Inner {
double weight = 200;
//内部类里面可以直接访问外部类的成员, 包括私有成员
public void show() {
System.out.println(weight);
System.out.println(name);
System.out.println(age);
}
}
}
1.1.2. 私有成员内部类
- 私有成员内部类 就像私有成员变量一样,在外面无法直接访问
代码
- 这里通过外部类Outer的对象 调用了method方法, 访问了内部类里的成员
public class Test2Innerclass {
/*
私有成员内部类演示
*/
public static void main(String[] args) {
//私有成员内部类 就像私有成员变量一样,在外面无法直接访问
// Outer.Inner oi = new Outer().new Inner();
Outer outer = new Outer();
//通过外部类的method方法 访问了内部类里的成员
outer.method();
}
}
class Outer {
private int age;
//私有成员内部类
private class Inner {
public void show(){
System.out.println("inner..show");
}
}
public void method(){
Inner i = new Inner();
i.show();
}
}
1.2. 静态成员内部类
- 创建对象的格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();
1.2.1. 代码
- 访问静态内部类里的静态方法, 外部类名.内部类名.静态方法()
- 静态内部类Inner里的show方法和eat方法中,不能访问外部非静态成员,只能访问静态的
public class Test3Innerclass {
/*
静态成员内部类演示
*/
public static void main(String[] args) {
// 外部类名.内部类名 对象名 = new 外部类名.内部类名();
Outer.Inner oi = new Outer.Inner();
oi.show();
//访问静态内部类里的静态方法
Outer.Inner.method();
}
}
class Outer {
int age;
static String name = "halon";
public static void method() {
System.out.println(name);
//System.out.println(age);//不能调用非静态的
}
static class Inner {
int height = 30;
public void show() {
System.out.println(height);
method();
System.out.println(name);
//System.out.println(age);//不能调用外部类的非静态的
}
public static void eat() {
System.out.println("吃");
System.out.println(num);
//System.out.println(name);//不能调用外部类的非静态的
}
}
}
1.2.2. 非静态内部类不能有静态成员(jdk16之前)
代码
- Inner类中不能有静态的变量和静态的方法
1.2.3. 静态的内部类不能访问外部的非静态的成员员
- 静态内部类Inner不能访问外部的非静态变量num
class Outer {
int num = 10;
static class Inner {
public void show() {
//静态内部类 不能访问外部的非静态成员
// System.out.println(num);
}
public static void method() {
System.out.println("inner..method");
}
}
}
1.3. 局部内部类
1.3.1. 代码
- 类Inner定义在method方法里,也只能在method方法内部使用
public class Test4Innerclass {
/*
局部内部类:
编写位置: 方法中
访问方式: 只能在方法中, 创建对象并访问
*/
public static void main(String[] args) {
Outer o = new Outer();
o.method();
}
}
class Outer {
int a = 10;
public void method() {
int b = 20;
class Inner {
public void show() {
System.out.println("show...");
System.out.println(a);
System.out.println(b);
}
}
Inner i = new Inner();
i.show();
}
}
1.4. 外部类.this (内部类里访问外部类变量)
- 在内部类访问外部的成员
- 如下代码中 show方法里Outer.this.age
public class Demo01 {
public static void main(String[] args) {
//外部类名.内部类名 对象名 = new 外部类名.内部类名();
Outer.Inner inner = new Outer().new Inner();
inner.show();
}
}
class Outer {
int age = 10;
public void eat() {
System.out.println(this.age);
}
class Inner {
int age = 20;
public void show() {
int age = 30;
System.out.println(age);
System.out.println(this.age);
System.out.println(Outer.this.age);
}
}
}
1.5. 匿名内部类
1.5.1. 匿名内部类的前提
- 存在一个普通类或者抽象类或者接口
1.5.2. 语法
new 类名/接口名 (){
重写方法
};
1.5.3. 匿名内部类的本质
- 本质:是一个继承了该类或者实现了该接口的匿名子类的对象
1.5.4. 案例1:用接口
接口代码
interface Inter {
void show();
}
实现代码
- 这个过程的理解
- 1 创建了一个实现了Inter的类,是匿名的
- 2 实现了接口的方法,写在大括号内
- 3 创建了这个实现类的对象
- 4 用这个对象调用了实现的show方法
new Inter() {
@Override
public void show() {
System.out.println("我是匿名内部类中的show方法");
}
}.show();
1.5.5. 案例2:用接口
接口代码
interface Inter2 {
void show1();
void show2();
}
实现代码
- 这个过程的理解
- 1 创建了一个实现了Inter1的类,是匿名的
- 2 实现了接口的方法show1和show2,写在大括号内
- 3 创建了这个实现类的对象,赋值给了变量i
- 4 用这个对象i,调用了实现的show1方法和show2方法
public class Demo02 {
public static void main(String[] args) {
Inter1 i1 = new Inter1() {
@Override
public void show1() {
System.out.println("show1");
}
@Override
public void show2() {
System.out.println("show2");
}
};
i1.show1();
i1.show2();
}
}
1.5.6. 案例3:用抽象类
抽象类代码
abstract class Animal {
abstract void eat();
public void drink() {
System.out.println("喝点豆浆");
}
}
实现代码
- 这个过程的理解
- 1 创建了一个继承了Animal的子类,是匿名的
- 2 实现了Animal类的方法eat和drink,写在大括号内,这里drink不强制重写
- 3 创建了这个子类的对象,赋值给了变量a
- 4 用这个对象a,调用了实现的eat方法和drink方法
public class Demo01 {
public static void main(String[] args) {
Animal a = new Animal() {
@Override
void eat() {
System.out.println("吃猫粮");
}
@Override
public void drink() {
System.out.println("喝雪碧");
}
};
start(a);
start(new Animal() {
@Override
void eat() {
System.out.println("吃鱼食");
}
});
}
public static void start(Animal a) {
a.eat();
a.drink();
}
}
1.5.7. 案例4:用普通类
类代码
public class Animal {
public void jump() {
System.out.println("大跳");
}
}
实现代码
- 这个过程的理解
- 1 创建了一个继承了Animal1的子类,是匿名的
- 2 实现了Animal类的方法jump,写在大括号内,这里jump不强制重写
- 3 创建了这个子类的对象,赋值给了变量a1
public class Demo01 {
public static void main(String[] args) {
Animal a1 = new Animal() {
@Override
public void jump() {
System.out.println("重写了跳跃方法");
}
};
a1.jump();
//创建了Animal的对象
new Animal();
//创建了Animal的子类的对象
new Animal(){};
}
}
1.6.1. 匿名内部类的应用
1.6.1. 案例
接口代码
package com.heima.test13;
/*
游泳接口
*/
interface Swimming {
void swim();
}
实现代码
class Person implements Swimming {
@Override
public void swim() {
System.out.println("自由泳");
}
}
package com.heima.test13;
public class Demo01 {
public static void main(String[] args) {
// 方案1
//创建Person对象
Person p01 = new Person();
//传入对象 去游泳
goSwim(p01);
//方案2
Swimming swimming = new Swimming() {
@Override
public void swim() {
System.out.println("蛙泳");
}
};
goSwim(swimming);
//方案3
goSwim(new Swimming() {
@Override
public void swim() {
System.out.println("蝶泳");
}
});
}
//去游泳, 传入Swimming接口的实现类对象
public static void goSwim(Swimming s) {
s.swim();
}
}
Comments NOTHING