Java语法学习内部类

Java语法学习局部类

大纲

  1. 基本语法
  2. 四种内部类
  3. 局部内部类
  4. 匿名内部类
  5. 成员内部类
  6. 静态内部类

具体案例

1.基本语法与优点

在这里插入图片描述

2.内部类的分类

在这里插入图片描述

3.局部内部类

(本质上可以理解为一个类的局部位置比如方法里面的局部变量,只不过是类罢了)
在这里插入图片描述
在这里插入图片描述

下面是注解

1. 对于第一点
public class outer {
    private int n1 = 10;//外部类的私有属性
    public void m1(){//外部类的一个方法
        class inner{//在这个方法内部创建了一个局部内部类
            public void innerWay(){//在这个局部内部类里可以调用外部类的所有成员包括私有的
                System.out.println(n1);
            }
        }
    }
}

2.对于第二点

本质上可以理解为一个类的局部位置比如方法里面的局部变量,只不过是类罢了,所以它有局部变量的特点(不能用修饰符修饰,final除外),同时兼顾类的继承特点

class a{};
public class outer {
    private int n1 = 10;//外部类的私有属性
    public void m1(){//外部类的一个方法
        class inner{//在这个方法内部创建了一个局部内部类
            public void innerWay(){//在这个局部内部类里可以调用外部类的所有成员包括私有的
                System.out.println(n1);
            }
        }
        class inner2 extends inner{};
    }
}

3. 对于第三点

因为是局部变量,所以它的作用范围也只能定义它的代码块当中,如下,同一个外部类里面方法2的局部内部类是不能继承方法1的局部内部类的

public class outer {
    private int n1 = 10;//外部类的私有属性
    public void m1(){//外部类的一个方法
        class inner{//在这个方法内部创建了一个局部内部类
            public void innerWay(){//在这个局部内部类里可以调用外部类的所有成员包括私有的
                System.out.println(n1);
            }
        }
        class inner2 extends inner{};//同一个代码块的可以继承
    }
    public void m2(){
        class inner3 extends inner//因为局部内部类是局部变量
        // 所以不能继承另一个代码块里的局部内部类
    }
}

4. 对于第五点

外部类通过在方法体中创建局部内部类的实例化 调用局部内部类成员 的成员,然后在主方法中创建外部类的实例,调用,方法,方法里有内部类的实例,然后内部类的实例最后调用内部类的

public class outer {
    private int n1 = 10;//外部类的私有属性

    public void m1() {//外部类的一个方法
        class inner {//在这个方法内部创建了一个局部内部类

            public void innerWay() {//在这个局部内部类里可以调用外部类的所有成员包括私有的
                System.out.println(n1);
            }
        }
        inner Inner = new inner();//在局部内部类存在的方法或代码块内创建其对象
        // 再调用它你想要调用的方法,就可以完成对其的访问
        Inner.innerWay();
    }//m1方法的花括号
}

就是在局部内部类存在的那个方法或者代码块里创建它的对象,再实现对它方法的调用

public class t {
    public static void main(String[] args) {
        outer outer = new outer();
        outer.m1();
    }
}
5.对于第七点

如果局部内部类有属性和外部类重名,这在该方法里的访问是就近原则直接访问局部内部类的属性,如果要访问外部类的属性,需要:外部类.this.属性名,的方法访问

public class outer {
    private int n1 = 10;//外部类的私有属性
    public void m1() {//外部类的一个方法
        class inner {//在这个方法内部创建了一个局部内部类
            public  int n1 = 100;
            public void innerWay() {
                System.out.println(n1);
            }
        }
        System.out.println(n1);//访问的是内部类的n1 = 100
        System.out.println(outer.this.n1);//访问的是外部类的n1 = 10
    }//m1方法的花括号
}

而对于重名的方法,直接调用是外部类的方法,而内部类的方法调用需要创建对象去访问

总结

局部内部类本质上同时有局部变量和类的特点

  1. 局部变量:
    局部变量的作用域,导致内部可以访问外部,但是外部不能直接访问内部 ,而如果想访问重名的外部类的属性,需要:外部类.this.属性
    局部变量没有修饰符(但是类可以用final),本质上属于外部类,所以可以访问外部类的private
  2. 类:
    访问局部内部类需要创建对象才能访问,局部内部类也可以继承,实现接口,但是要在同一个作用域才行(局部内部类也可以继承外部其它类),也可以有属性,方法,代码块,构造器,内部类

4.匿名内部类

在这里插入图片描述
注意:匿名内部类一般定义在局部位置(方法内),也可以直接定义在成员位置

接口形式

public class outer {
   IG ig = new IG() {
       @Override
       public void use() {
           System.out.println("ig在使用");
       }
   };//我们知道接口是不能实例化的,但是作为匿名内部类的运行机制
    // 这里的底层系统给我们分配了一个系统创建名字的类去完成该接口的实现
    //然后把这个类的地址返回给我们的引用对象
    // 然后可以理解系统创建的那个模板(类)没有了,但是对象还在
    IG ig2 = new IG() {//这里等于是底层创新又定义一个类,
        //我们重新实现接口后,类销毁,地址返回给这个ig2的引用对象
        @Override
        public void use() {
            System.out.println("ig2在使用");
        }
    };
   public void way(){
       ig.use();
       ig2.use();
   }
}
interface IG{
    void use();
}

我们知道接口是不能实例化的,但是作为匿名内部类的运行机制,这里的底层系统给我们分配了一个系统创建名字的类去完成该接口的实现 ,然后把这个类的地址返回给我们的引用对象,然后可以理解系统创建的那个模板(类)没有了,但是对象还在。

类形式

package learn;
public class outer {
   Animal animal = new Animal(){
       public int a = 100;//自己创建的属性
     public void eat(){//对父类方法的重写
         System.out.println(age);
         System.out.println(a);//调用自己创建的属性
         sleep();//调用自己创建的方法
     }
     public void sleep(){
         System.out.println("sleep");
     }
   };
   public void method(){
       animal.eat();//调用匿名内部对象的方法
   }
}
class Animal{//父类
    public int age = 10;
    static {
        System.out.println("静态代码块");
    }//父类的静态代码块,加载的时候会显示
    public void eat(){
        System.out.println("Animal");
    }
}

作为匿名内部类的运行机制,这里的底层系统给我们分配了一个系统创建名字的子类去继承父类(我们等号左的那个类)(这个时候也会完成父类的加载)然后把这个子类的地址返回给我们的引用对象,然后可以理解系统创建的那个模板(类)没有了,但是对象还在。(这种比较类似于向上转型,我们只能直接调用编译类型的属性和方法(当然可以重写,也可以创建这个类的其它方法和属性,最后在重写的方法里面体现出来))
当然如果继承的是抽象类,就必须重写他的方法

使用与细节

在这里插入图片描述
在这里插入图片描述
因为还是在外部类中,所以还是可以访问外部类的私有属性。
在这里插入图片描述

注意:

匿名内部类一般定义在局部位置(方法内),也可以直接定义在成员位置,如果定义在局部位置,就是局部变量,才遵循第四点,与第五点

5.成员内部类

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

注解

对于第六点:

  1. 第一种:
    语法:首先创建一个外部类的对象,然后,外部类名.内部类名.引用名 = 对象名(前面创建的). new 内部类名
    这种类似于先创建对象,再对对象的某个成员赋值
class outer {
    class inner{
        public void say(){
            System.out.println("我在说话");
        }
    }
}
public class t {
    public static void main(String[] args) {
        outer out = new outer();//创建一个外部类的对象
        outer.inner one = out.new inner();//用这个对象创建内部类的对象
    }
}

还可以直接创建:

 outer.inner one = new outer().new inner();//直接创建
  1. 第二种:
    在外部类创建一个方法,返回内部类
class outer {
    class inner{
        public void say(){
            System.out.println("我在说话");
        }
    }
    public inner getinner(){
        return new inner();//在外部类创建一个方法,返回内部类
    }
}
public class t {
    public static void main(String[] args) {
        outer out = new outer();//创建一个外部类的对象
        outer.inner one = out.getinner();//用这个对象的方法返回成员内部类
    }
}

总结

与局部内部类差别在所处的位置。所以在作用域和修饰符方面,成员内部类更包容一些,而对于类的特点,没有改变(也有属性,构造器,方法,内部类,代码块),可以继承,与实现接口,并且外部其他类可以访问成员内部类

6.静态内部类

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

注解

对于第六点
在成员内部类的基础上增加了静态的调用机制

  1. 直接调用静态成员来创建
  2. 调用静态方法返回
  3. 创建外部类的一个对象后调用成员方法
  4. (但是不能直接使用两个new创建)
    对于第七点
    因为是静态,就不需要this来访问外部类的成员了
class outer {
    static class inner{
        public void say(){
            System.out.println("我在说话");
        }
    }
    public inner getinner(){
        return new inner();//在外部类创建一个方法,返回内部类
    }
    public static inner getStaticinner(){
        return new inner();//在外部类创建静态方法返回对象
    }
}
public class t {
    public static void main(String[] args) {
        outer.inner one = new outer.inner();//直接调用静态成员来创建
        outer.inner two = outer.getStaticinner();//调用静态方法返回
        outer.inner three = new outer().getinner();//创建外部类的一个对象后调用成员方法
    }
}

总结

在成员内部类的基础上增加了静态的属性,导致在访问时,有静态的特点,和在外部其他类创建静态局部类时,略有不同

  • 44
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

挽天java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值