一、内部类是什么?
/*
内部类:一个类中包含另一个类,例如:摩托车包含发动机
内部类简单分为两种:
1.成员内部类
2.局部内部类,局部内部类还包含匿名内部类
*/
二、成员内部类
1.成员内部类定义
/*
成员内部类:在一个类中定义一个类,作为成员
1. 定义格式:
修饰符 class 类名称{
....
修饰符 class 成员内部类名称{
....
}
}
2.注意事项:
内部类访问外部类变量随意访问,而外部类访问内部类则需要在外部类中创建内部类对象
简言之"内访外,随意访问,外访内,需创对象"
访问格式:外部类名称.内部类名称 对象名
*/
public class Demo02 {
private String name = "mary";
//定义一个成员内部类
public class demo02Part{
public void method02(){
System.out.println(name);//内部类可以随意访问外部类成员变量
}
}
public void method01(){
//1.间接访问:在外部类方法中创建内部类对象进行访问
demo02Part demo02 = new demo02Part();
demo02.method02();
System.out.println("外部类方法");
}
}
2.成员内部类访问规则
/*成员内部类访问:
1.间接访问:在外部类方法中创建内部类对象进行访问,然后通过main方法访问外部方法
2.直接访问格式:外部类名称.内部类名称 对象名 = new 外部类名称().内部类名称();
*/
public class Demo03 {
public static void main(String[] args) {
//1.间接访问:在外部类方法中创建内部类对象进行访问,然后通过main方法访问外部方法
Demo02 demo = new Demo02();
demo.method01();//结果:mary 外部类方法
//2.直接访问格式:外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();
Demo02.demo02Part demo01 = new Demo02().new demo02Part();
demo01.method02();//结果:mary
}
}
3.成员内部同名变量访问规则
/*
成员内部类同名变量访问规则
1.变量名 就近原则,访问的为成员方法中的局部变量
2.this.name 访问的是内部类中的成员变量
3.外部类名称.this.变量名 访问的是外部类的成员变量
*/
public class Demo04 {
private String name="mary";//外部类成员变量
public class demo04Part{
private String name="jack";//内部类的成员变量
public void method(){
String name="henry";//成员方法中的局部变量
System.out.println(name);//就近原则,访问的为成员方法中的局部变量
System.out.println(this.name);//访问的是内部类的成员变量
System.out.println(Demo04.this.name);//访问的是外部类的成员变量
}
}
}
二、局部内部类
/*局部内部类:定义在方法内部的类,只能在方法内部使用,方法外部无法直接访问
定义格式:修饰符 返回值类型 方法名称(参数列表){
class 局部内部类名称{
......
}
}
注意事项:1.局部内部类定义时class前不加任何修饰符
2.局部内部类访问的方法中的局部变量需要为final修饰有效不可变类型
*和生命周期有关,new出来的东西都在堆中,等到垃圾回收时才会消失
*方法和方法的局部变量在栈中,调用时加载进栈,使用完成立即出栈消失
*局部内部类的生命周期比它所属的方法要长,当方法使用完成时但是局部
内部类还需要继续使用方法中的局部变量时,局部内部类会拷贝一份局部
变量的值,如果局部变量的值是变化的,局部内部类无法确定哪一个值是
需要拷贝的,因此需要保证局部内部类使用的方法的局部变量为不可变的
局部内部类使用: 因为只能在方法内部使用,所以只能在方法内部创建对象,然后在main方法中创建外部类对象,然后调用方法进行使用
*/
public class Demo05 {
public void method(){
/*final*/ int num=10;//final写上更保险,即使不写,也需要保证局部内部类访问的成员变量值不能改变
//num = 50;//错误写法
//num = 10;//错误写法
class demo05Part{
public void method01(){
System.out.println(num);
}
}
demo05Part demo = new demo05Part();
demo.method01();
}
}
三、匿名内部类
/*匿名内部类:简单来说就是没有名字的类,如果接口的实现类(或者父类的子类)只使用唯一的一次,即可使用匿名内部类
定义格式:接口名称 对象名 = new 接口名称(){
......
};
定义注意事项: 1.new是创建对象的动作
2.接口名称()指的是要实现的接口
3.{....}为匿名类的内容
其余注意事项: 1. 匿名类创建对象时只能使用唯一的一次
2. 如果需要创建多个匿名内部类对象,且类的内容一样的话,就必须创建实现类对象
3. 匿名内部类和匿名对象意义不同,匿名内部类有对象名,无类名,而匿名对象既无类名,也无对象名
匿名对象调用方法时只能调用一次,如需调用多个方法,只能创建多个匿名类对象,要想一
个对象调用多个方法,就必须给这个对象取名字
*/
public class Demo06 {
public static void main(String[] args) {
Demo07 demo07 = new Demo07(){
@Override
public void method01() {
System.out.println("匿名类实现接口的方法-1");
}
@Override
public void method02() {
System.out.println("匿名类实现接口的方法-2");
}
};
demo07.method01();//结果:匿名类实现接口的方法-1
demo07.method02();//结果:匿名类实现接口的方法-2
//Demo07 demo07 = new Demo07() 错误写法,接口不能直接new
//1. 匿名类创建对象时只能使用唯一的一次
Demo07 demo08 = new Demo07(){
@Override
public void method01() {
System.out.println("匿名类实现接口的方法-3");
}
@Override
public void method02() {
System.out.println("匿名类实现接口的方法-4");
}
};
demo08.method01();//结果:匿名类实现接口的方法-3
demo08.method02();//结果:匿名类实现接口的方法-4
//2.匿名类省略类名,但是没有省略对象名,如上面的demo07,demo08都是对象名
// 匿名对象既省略类名,也省略对象名,如下
new Demo07(){
public void method01() {
System.out.println("匿名类实现接口的方法-5");
}
public void method02() {
System.out.println("匿名类实现接口的方法-6");
}
}.method01();//结果:匿名类实现接口的方法-5
// 3.匿名对象调用方法时只能调用一次,如需调用多个方法,只能创建多个匿名类对象
new Demo07(){
public void method01() {
System.out.println("匿名类实现接口的方法-5");
}
public void method02() {
System.out.println("匿名类实现接口的方法-6");
}
}.method02();//结果:匿名类实现接口的方法-6
}
}
总结
本文讲解了Java中内部类的相关知识,主要包括成员内部类、局部内部类,匿名内部类属于局部内部类,并进行了代码的实现,如有不足,敬请指正!