内部类

内部类

概念

内部类的概念:将一个类定义在另一个类中

内部类的分类

  • 按定义的位置来分

    1. 成员内部内,类定义在了成员位置 (类中方法外称为成员位置,无static修饰的内部类)
    2. 静态内部类,类定义在了成员位置 (类中方法外称为成员位置,有static修饰的内部类)
    3. 局部内部类,类定义在方法内
    4. 匿名内部类,没有名字的内部类,可以在方法中,也可以在类中方法外。

    成员内部类的细节

    编写成员内部类的注意点:

    1. 成员内部类可以被一些修饰符所修饰,比如: private,默认,protected,public,static等
    2. 在成员内部类里面,JDK16之前不能定义静态变量,JDK16开始才可以定义静态变量。
    3. 创建内部类对象时,对象中有一个隐含的Outer.this记录外部类对象的地址值。

例子

class B{
    //成员内部类
//    class A{
//
//
//    }

    public void fun1(){
        //局部内部类
        class A{
        }
    }

}
class Demo1{
    int a = 10; // 成员变量

    public void fun1(){
        int b = 20; // 局部变量
    }
}

public class InnerClassDemo1 {
    public static void main(String[] args) {

    }
}

成员内部类可以使用外部内中的任意权限修饰符修饰的成员变量

例子
/**
 *  使用static关键字修饰成员内部类
 */
class Outer1{
    static int a = 10;
    private static int b = 20;

    //成员内部类
    static class Inner1{
        int c = 20;
        public void show1(){
            System.out.println(a); // 成员内部类可以使用外部内中的任意权限修饰符修饰的成员变量
            System.out.println(b);
            c = 100;
            System.out.println(c);
        }
    }

}
//class Outer1{
//    int a = 10;
//    private int b = 20;
//
//    //成员内部类
//    private class Inner1{
//        int c = 20;
//        public void show1(){
//            System.out.println(a); // 成员内部类可以使用外部内中的任意权限修饰符修饰的成员变量
//            System.out.println(b);
//            c = 100;
//            System.out.println(c);
//        }
//    }
//
//    public void fun1(){
//        Inner1 inner1 = new Inner1();
//        inner1.show1();
//    }
//
//}

静态成员内部类

1.格式:直接在定义内部类的时候加上static关键字
  public class A{
      static class B{
          
      }
  }

2.注意:
  a.内部类可以定义属性,方法,构造等
  b.静态内部类可以被final或者abstract修饰
    被final修饰之后,不能被继承
    被abstract修饰之后,不能new
  c.静态内部类不能调用外部的非静态成员
  d.内部类还可以被四种权限修饰符修饰
      
3.调用静态内部类成员:
  外部类.内部类 对象名 = new 外部类.内部类()
public class Person {
    public void eat(){
        System.out.println("人要干饭");
    }

    static class Heart{
        public void jump(){
            System.out.println("心脏哐哐哐跳");
        }
    }
}
public class Test01 {
    public static void main(String[] args) {
       // 外部类.内部类 对象名 = new 外部类.内部类()
        Person.Heart heart = new Person.Heart();
        heart.jump();
    }
}

非静态成员内部类

1.格式:直接在定义内部类的时候加上static关键字
  public class A{
      class B{
          
      }
  }

2.注意:
  a.内部类可以定义属性,方法,构造等
  b.静态内部类可以被final或者abstract修饰
    被final修饰之后,不能被继承
    被abstract修饰之后,不能new
  c.静态内部类不能调用外部的非静态成员
  d.内部类还可以被四种权限修饰符修饰
      
3.调用非静态内部类成员:
  外部类.内部类 对象名 = new 外部类().new 内部类()

例子

public class Person {
    public void eat(){
        System.out.println("人要干饭");
    }

    class Heart{
        public void jump(){
            System.out.println("心脏哐哐哐跳");
        }
    }
}
public class Test01 {
    public static void main(String[] args) {
       // 外部类.内部类 对象名 = new 外部类().new 内部类()
        Person.Heart heart = new Person(). new Heart();
        heart.jump();
    }
}

局部内部类

定义:

  • 局部内部类是定义在方法或作用域内部的类。它就像是方法内部的一个局部变量,只不过这个 “变量” 是一个类。

例子

public class Person {
    public void eat(){
        class Heart{
            public void jump(){
                System.out.println("杨浩东真帅");
            }
        }

        new Heart().jump();
    }
}
public class Person {
    public void eat(){
        class Heart{
            public void jump(){
                System.out.println("心脏哐哐哐的跳");
            }
        }

        new Heart().jump();
    }
}

抽象类作为方法参数和返回值

1.抽象类作为方法参数传递,传递实参时,传递的是其子类对象

2.抽象类作为方法返回值类型返回时,实际返回的是其子类对象

public abstract class Animal {
    public abstract void eat();
}
public class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗啃骨头");
    }
}
public class Test02 {
    public static void main(String[] args) {
        Dog dog = new Dog();
        method01(dog);
        System.out.println("=================");
        Animal animal = method02();//Animal animal = new Dog()
        animal.eat();
    }

    public static void method01(Animal animal){//Animal animal = dog
        animal.eat();
    }

    public static Animal method02(){
        return new Dog();
    }
}

匿名内部类

定义

所谓的匿名内部类,可以理解为没有显式声明出类名的内部类

匿名内部类
     语句定义格式:
         new 类|抽象类|接口(){
             方法的重写;
         }
     由JVM自己底层造了一个类去继承或者实现我们的类或者接口,我们只需要关注方法的重写逻辑就可以了,然后JVM把这个没有名字的类
     造一个对应的对象。

特点

  1. 定义一个没有名字的内部类
  2. 这个类实现了父类,或者父类接口
  3. 匿名内部类会创建这个没有名字的类的对象

例子

abstract class Demo3{
    public abstract void fun1();
}
//class Demo3Zi2 extends Demo3{
//    @Override
//    public void fun1() {
//        System.out.println("张成阳真帅!");
//    }
//}
//
//class Demo3Zi extends Demo3{
//    @Override
//    public void fun1() {
//        System.out.println("好好学习,天天向上!");
//    }
//}

class Demo3Test{
    public void show1(Demo3 demo3){
        demo3.fun1();
    }
}

public class NiMingClassDemo1 {
    public static void main(String[] args) {
        Demo3Test demo3Test = new Demo3Test();
//        demo3Test.show1(new Demo3Zi());
//        demo3Test.show1(new Demo3Zi2());

        demo3Test.show1(new Demo3() {
            @Override
            public void fun1() {
                System.out.println("好好学习,天天向上!");
            }
        });
    }
}

1.什么时候使用匿名内部类:

​ 当简单调用一次接口中的方法,我们就可以使用匿名内部类

2.将一种格式代表实现类对象或者子类对象来看待,来学习

3.匿名内部类会编译生成的,咱们不要管,我们只需要利用咱们讲的格式去new对象,调用重写的方法即可

匿名内部类复杂用法_当参数传递

public interface USB {
    void open();
}
public class Test01 {
    public static void main(String[] args) {
        method01(new USB() {
            @Override
            public void open() {
                System.out.println("usb打开了");
            }
        });
    }
    public static void method01(USB usb){
        usb.open();
    }
}

匿名内部类复杂用法_当返回值返回

public interface USB {
    void open();
}
public class Test02 {
    public static void main(String[] args) {
        USB usb = method01();
        usb.open();

    }

    public static USB method01(){
        return new USB() {
            @Override
            public void open() {
                System.out.println("USB打开了");
            }
        };
    }
}

posted @   09250327  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示