内部类分为成员内部类和局部内部类(匿名内部类)
成员内部类
public class body{
public class heart{
}
}
注意:内用外,随意访问,外用内,需要定义内部类队象。
使用方法:
1.通过外部类方法间接调用内部类
//内部类和外部类
public class Body {//外部类
public void method() {//通过外部类方法间接调用内部类
System.out.println("外部类方法");
Heart heart = new Heart();
heart.beat();
}
//通过外部类调用内部类
public class Heart{//内部类
public void beat(){
System.out.println("心脏跳动嘣嘣嘣");
}
}
}
//主类
public class demo01main {
public static void main(String[] args) {
Body body = new Body();
body.method();
}
}
2.直接调用内部类
//内部类和外部类
public class Body {//外部类
public void method() {
System.out.println("外部类方法");
}
public class Heart{//内部类
public void beat(){
System.out.println("心脏跳动嘣嘣嘣");
}
}
}
//主类
public class demo01main {
public static void main(String[] args) {
Body.Heart heart = new Body().new Heart();//通过直接方式访问内部类
heart.beat();
}
}
如何访问内部类的同名变量
public class Outter {
int num = 10;
public class Inner{
int num = 20;
public void method(){
int num = 30;
System.out.println(num);//内部类方法的局部变量
System.out.println(this.num);//内部类的成员变量
//内部类方法访问外部类的成员变量的时候,格式是:外部类名.this.成员变量名
System.out.println(Outter.this.num);//外部类的成员变量
}
}
}
局部内部类
- 定义在类的方法中的类叫局部内部类。局部只有在方法中才能用它,在方法外不能使用。如果想使用它,就在方法中创建对象使用它。
- 需要注意的是,在外部类中的方法中定义的局部内部类,类名前不能加权限修饰符,只能是默认的default。
格式:
public class MyClass {
public void method(){//外部类的方法
class son{//在外部类的方法中定义一个类
}
}
}
小结一下内部类中的权限修饰符
- 外部类 public/default
- 成员内部类 public/protect/default/private
- 局部内部类 一个都不能写
补充:如果需要访问所在方法的局部变量,那这个变量就是有效final的。即使不写final,也是final的。
public void method(){//外部类的方法
int num = 10;//即使不写final,也是final的,在局部内部类中不能被改变
class son{//在外部类的方法中定义一个类
public void methodson(){
System.out.println("num");
}
}
}
}
匿名内部类(重点)
何时使用?
如果接口的实现类(或父类的子类)只需要使用唯一的一次,
那么这种情况下就可以省略掉该类的定义,而使用匿名内部类
如何定义匿名内部类?
/*
格式:
接口名称 对象名 = new 接口名称{
覆盖重写接口中的所有方法;
};//记得加分号
*/
//接口
public interface MyInterface {
public abstract void method();
}
//主类
public class demoMain {
MyInterface impl = new MyInterface() {//大括号中的内容就相当于实现类中的内容(如下的参考类)
@Override
public void method() {
}
};
}
//做参考的实现类
public class MyInterfaceImpl implements MyInterface {
@Override
public void method() {
System.out.println("实现类中的覆盖重写方法执行了");
}
}
使用匿名内部类的好处?
如果不使用匿名内部类,想要用接口中的内容就必须定义一个实现类,并且如果只用一次接口中的方法的话,单独定义一个实现类未免太浪费了。如果使用了匿名内部类,那么就不需要定义实现类了。
对格式new 接口名称 () {…} 进行解析
- new 代表创建的动作。
- 接口名称就是匿名内部类实现哪个接口。
- {…}才是匿名内部类的内容。
还有点注意事项
- 匿名内部类只能使用唯一的一次,就是在创建对象的时候。
- 如果想要多次使用,就需要再创建一个新的对象。
匿名内部类与匿名对象的区别
匿名内部类是省略了【实现类/子类的名称】,可以有对象名称。但是匿名对象是省略了【对象名称】。