目录
- 1.内部类介绍
- (1)为啥需要内部类
- (2)内部类有:
- (2.1)成员内部类
- (2.2)静态内部类
- (2.3)局部内部类
- (2.4)匿名内部类
- 权限符修饰规则
1.内部类介绍
A类中定义一个B类
(1)为啥需要内部类
1、 内部类方法可以访问该类定义所在的作用域中的数据,包括私有数据。
2、内部类可以对同一个包中的其他类隐藏起来。
3、 当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷。
(2)内部类有:
- 成员内部类
- 静态内部类
- 局部内部类
- 匿名内部类
(2.1)成员内部类
特点:
(1)存在于某个类的内部,与全局属性或者方法同级的内部类就是成员内部类
(2)成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括静态成员和私有成员)。内部类调用外部类,可以随意调用
(3)外部类必须通过成员内部类的对象来访问内部类的属性和方法。
间接使用:在外部类的方法中,使用内部类,然后在main中调用外部类的方法来实现内部类的调用
直接使用:直接创建内部类对象进行调用
外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();
(4)内部类的同名变量访问
如果出现了重名现象,那么内部类调用外部类的成员变量格式为:
外部类名称.this.外部类成员变量名
(5)成员内部类可以有public\private\protected以及默认访问权限。
(6)成员内部类,不能声明static成员变量
import java.io.OutputStream;
public class Outer {
private int id=10;
private String name="章程";
private String sex="女";
class Inner{
String sex="男";//内部类、外部类重名
private void getInfo(){
System.out.println("内部类可以直接使用外部类成员属性:"+id);
System.out.println("内部类可以直接使用外部类成员方法:" + getName());
System.out.println("内部类外部类重名-调用内部类成员变量sex:"+this.sex);
System.out.println("内部类外部类重名-调用外部类成员变量sex:"+Outer.this.sex);
}
}
private String getName(){
return name;
}
public void out(){
System.out.println("外部类调用内部类方法,需要通过内部类对象调用");
Inner inner=new Inner();
inner.getInfo();
}
public static void main(String[] args) {
System.out.println("间接使用成员内部类:在main中调用外部类的方法来实现内部类的调用");
Outer outer=new Outer();
outer.out();
System.out.println("直接使用成员内部类:外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();");
Outer.Inner inner=new Outer().new Inner();
inner.getInfo();
}
}
(2.2)静态内部类
在成员内部类的基础上加上一个static关键字就是静态内部类
特点:
1、不需要依赖外部类。
2、不能使用外部类的非静态属性和方法。
3、静态内部类可以定义静态或非静态成员
/**
* @author zhaomin
* @date 2023/2/10 14:29
*/
public class Outer1 {
private static int age=10;
private static String name="huahua";
private static String getName(){
return name;
}
static class Inner{
String sex="女";
static String add="西安";
private void getInfo(){
System.out.println("静态内部类可以访问外部类的静态成员变量:"+age);//非静态不可以
System.out.println("静态内部类调用外部类的静态方法:"+getName());//非静态不可以
System.out.println("静态内部类可以定义非静态成员:"+sex);
System.out.println("静态内部类可以定义静态成员:"+add);
}
}
public static void main(String[] args) {
System.out.println("外部类可以直接实例化内部类对象进行方法调用,不需要依赖外部类");
Inner inner=new Inner();
inner.getInfo();
Outer1.Inner inner1=new Inner();
inner1.getInfo();
}
}
(2.3)局部内部类
特点
(1)局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内;
(2)局部内部类不可使用private、public、protected和static等修饰符, 同局部变量相同;
(3)局部内部类可以直接访问方法中的属性
(4)局部内部类 可以直接访问方法外部类中属性和方法
(5)局部内部类 创建对象 要在方法内部 局部内部类的外部声明,也就是只能在定义局部内部类的方法或者作用域中实例化,只有当前所属的方法才能使用它
/**
* @author zhaomin
* @date 2023/2/10 14:55
*/
public class Outer3 {
String sex="男";
private String getAdd(){
return "西安市";
}
public void outer(){
String name="a";
class Inner{
int num=100;
public void getInfo(){
System.out.println("局部内部类获取方法中的变量:" + name);
System.out.println("局部内部类获取本类的变量:" + num);
System.out.println("局部内部类获取外部类的非静态变量:"+sex);
System.out.println("局部内部类获取外部类的非静态方法:"+getAdd());
}
}
System.out.println("在方法中实例化局部内部类对象");
Inner inner=new Inner();
inner.getInfo();
}
public static void main(String[] args) {
Outer3 outer3=new Outer3();
outer3.outer();
}
}
(2.4)匿名内部类
特点:
(1)匿名内部类不能定义任何静态成员、方法和类,只能创建匿名内部类的一个实例
(2)一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类,需要重写接口中的方法。
(3)从匿名内部类引用的本地变量必须是最终变量或实际上的最终变量
public class Mythread6 {
public class Mythread6 {
public static void main(String[] args) {
for(int i=0;i<3;i++){
final int temp=i;
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程"+temp);
}
}).start();
}
}
}
权限符修饰规则
1、外部类:public / (不写)
2、成员内部类、静态内部类:public / protected / (不写) / private
3、局部内部类:什么都不能写