内部类

内部类


内部类就是一个类在定义一个类,比如,A类中定义一个B类,那么B类相对A类来说就称为内部类,而A类相对于B类就是外部类了。

  1. 成员内部类
  2. 静态内部类
  3. 局部内部类
  4. 匿名内部类
成员内部类的定义格式:
修饰符  class  外部类名称{
    修饰符  class 内部类名称{
            //   。。。 
    }
    // ...
}

例子1

package oop.demo07;

public class Outer {

    private /*static*/ int id; /*这个static可以加可以不加*/

    public void out(){
        System.out.println("外部类的方法");
    }

    // 如果这个加一个static静态方法,情况就不一样了
    // 下面的id就会出现错误。因为加了static后,程序会首先加载出来
    // 没有声明的id,先出现肯定会报错,所以static应该加在上面的id上,那个先加载
    // 在class类里面的class就叫内部类
    // 成员内部类,四种修饰符中都可能写
    public /*static*/ class Inner{
        // 这个是内部类。这个叫成员内部类
        public void in(){
            System.out.println("这是内部类的方法");
        }

        // 内部类也可以哦获取外部类的私有属性
        public void getId(){
            System.out.println(id);
        }
    }
}

class A{
    // 这个在整个类的外面的类,java中可以有多个这样的class类。
    // 但是只能有一个public class 类
    public static void main(String[] args) {

    }
}
  • 在class类里面的class就叫内部类
  • 如果添加static的修饰符,那么先加载出那个属性或者方法。之所以报错就是因为是先加载的原因,导致没出生就有了。
  • 想要调用内部类里面的方法,肯定和之前一样通过实例化类,肯定是实例化内部类
    又因为在里面,所以通过外面类的引用调用
package oop.demo07;

public class Application {
    public static void main(String[] args) {
        Outer outer = new Outer();
        // 通过这个外部类来实实例化内部类
        // 想要调用内部类里面的方法,肯定和之前一样通过实例化类,这里肯定是实例化内部类
        // 又因为在里面,所以通过外面类的引用调用
        Outer.Inner inner = outer.new Inner();
        inner.in(); // 这是内部类的方法
        // 内部类里面调用外部类中的私有属性,所以
        inner.getId();
    }
}

例子2
如果一个类是定义在一个方法内部的,那么这就是一个局部内部类。
“局部”:只有当前所属的方法才能使用它,出了这个方法外面就不能使用了。

小结一下类的权限修饰符:
public > protected > (default) > private
定义一个类的时候,权限修饰规则:

  1. 外部类:public / (default)
  2. 成员内部类:public / protected / (default) / private
  3. 局部内部类:什么都不用写.
package oop.demo07;

public class Outer {

    // 局部内部类
    public void method(){
        // 局部内部类:定义在方法里面的内部类叫局部内部类
        // 局部内部类,不用写修饰符,直接class 局部内部类名
        class Inner{
            public void in(){
            }
        }
    }
}
package oop.demo07;

public class Application {
    public static void main(String[] args) {
//        Apple apple = new Apple();
        // 实例化Apple类得到的引用apple,是这个类对象的赋值。
        new Apple().eat(); // 这个叫做匿名初始化类,不用将实例保存到变量侯总

        // 本来接口是不能直接new的,但是如果要new只能使用匿名类,然后重写方法
        UserService userService = new UserService() {
            @Override
            public void hello() {
                
            }
        };
    }
}

class Apple{
    public void eat(){
        System.out.println("其中一个类的成员方法");
    }
}

interface UserService{
    void hello();
}

匿名内部类

匿名内部类:如果接口的实现类(或者是父类的子类)只需要使用唯一的一次。那么这种情况下就可以省略掉该类的定义,而改为【匿名内部类】
匿名内部类的定义格式:

接口名称  对象名 = new 接口名称(){
    // 覆盖重写所有的抽象方法
}

匿名内部类是省略了【实现类/子类名称】,但是匿名对象是省略了[对象名称]
强调:匿名内部类和匿名对象不是一回事!!!
匿名内部类相当于是替代那个接口的实现类的

 public static void main(String[] args) {
        // 创建实现类  前面是接口名 对象名 = new 实现类名
        /*MyInterface impl = new MyInterfaceImpl();
        impl.method1(); */ //覆盖重写了方法1

        //使用多态的写法 左父右子,左边写接口对象
       /* MyInterface obj = new MyInterfaceImpl();
        obj.method1();*/ //覆盖重写了方法1

        // 错误写法,不能直接new接口,而是要new实现类
//        MyInterface some = new MyInterface();

        // 使用匿名内部类,但是不是匿名对象,对象的名称就叫objA
        MyInterface objA = new MyInterface() {
            @Override
            public void method1() {
                System.out.println("匿名内部类实现了方法1aaa");
            }

            @Override
            public void method2() {
                System.out.println("匿名内部类是实现类方法2BBB");
            }
        };
        // 接口名后面的属于匿名内部类,
        objA.method1();  //匿名内部类实现了方法1aaa
        objA.method2();  // 匿名内部类是实现类方法2BBB

        System.out.println("======");

        // 使用了匿名内部类,而且省略了对象名称,也是匿名对象
        new MyInterface(){
            @Override
            public void method1(){
                System.out.println("匿名内部类实现了方法111-BBB");
            }
            @Override
            public void method2(){
                System.out.println("匿名内部类实现了方法!222-BBB");
            }
        }.method1();  // 因为没有名字所以,在匿名对象直接点.方法
        // 并且匿名对象是无法调用第二次方法,所以需要再创建一个匿名内部类的匿名对象
        new MyInterface(){

            @Override
            public void method1() {
                System.out.println("匿名内部类实现了方法111-BBB");
            }

            @Override
            public void method2() {
                System.out.println("匿名内部类实现了方法!222-BBB");
            }
        }.method2();
    }

类和接口都可以用作成员变量名

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值