JavaSE——面向对象11:内部类(局部内部类、匿名内部类、成员内部类、静态内部类)

news2024/11/25 21:41:05

目录

一、内部类基本介绍

(一)内部类定义

(二)内部类基本语法

(三)内部类代码示例

(四)内部类的分类

二、局部内部类

三、匿名内部类(重要)

(一)基本介绍

(二)基于接口的匿名内部类

(三)基于类的匿名内部类

(四)注意事项与使用细节

(五)匿名内部类的最佳实践——当做实参直接传递

(六)小练习

四、成员内部类

1.成员内部类是定义在外部类的成员位置,并且没有static修饰。

2.成员内部类可以添加任意的访问修饰符,因为它的地位就是一个成员

3.成员内部类可以直接访问外部类的所有成员,包含私有的

4.作用域:成员内部类的作用域为整个类体

6.外部类和成员内部类的成员重名访问规则

五、静态内部类

1.静态内部类是定义在外部类的成员位置,并且有static修饰

2.可以添加任意访问修饰符,因为它的地位就是一个成员

3.可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员

4.作用域:同其他的成员一样,为整个类体

5.外部其他类访问静态内部类的三种方式

6.如果外部类和静态内部类的成员重名访问规则

7.小练习


一、内部类基本介绍

(一)内部类定义

        一个类的内部,又完整地嵌套了另一个类结构,被嵌套的类称为内部类(inner class),嵌套其他类的类称为外部类(outer class)。内部类最大的特点就是,可以直接访问私有属性,并且可以体现类与类之间的包含关系。内部类也是重点内容,因为底层源码中有大量内部类。

        类的五大成员:属性、方法、构造器、代码块、内部类。

(二)内部类基本语法

class Outer{ // 外部类
    class Inner{ // 内部类
    }
}

class Other{ // 外部其它类
}

(三)内部类代码示例

// 外部类
class Outer {
    // 属性
    private int n1 = 10;

    // 构造器
    public Outer(int n1) {
        this.n1 = n1;
    }

    // 方法
    public void hi() {}

    // 代码块
    {
        System.out.println("这是一个代码块...");
    }

    // 内部类,在Outer类的内部
    class Inner {}
}

// 外部其它类
class Other {}

(四)内部类的分类

  • 定义在外部类局部位置上(比如方法内):
  1. 局部内部类(有类名)
  2. 匿名内部类(没有类名,非常常用!)
  • 定义在外部类的成员位置上:
  1. 成员内部类(没有static修饰)
  2. 静态内部类(使用static修饰)

二、局部内部类

1.局部内部类定义在外部类的局部位置,比如方法体,并且有类名。

class Outer02 {
    public void m1() {
        class Inner02 { // 局部内部类可以定义在方法中

        }
    }

    {   // 局部内部类也可以定义在代码块中
        class Inner03{}
    }
}

2.局部内部类的作用域:仅在定义它的方法或代码块中

3.局部内部类可以直接访问外部类的所有成员,包含私有的。

class Outer02 {
    private int n1 = 100;

    private void m2() {
        System.out.println("m2方法被执行...");
    }

    public void m1() {
        class Inner02 { // 局部内部类
            public void f1() {
                // 局部内部类可以直接访问外部类的私有属性
                System.out.println("n1=" + n1);
                // 局部内部类可以直接访问外部类的私有方法
                m2();
            }
        }
    }
}

4.外部类访问局部内部类的成员,必须先创建局部内部类对象,再调用方法

注意:必须在作用域中。

public class LocalInnerClass {
    public static void main(String[] args) {
        Outer02 outer02 = new Outer02();
        outer02.m1();
        // f2方法被执行...
        // n1=100
        // m2方法被执行...
    }
}

class Outer02 {
    private int n1 = 100;

    private void m2() {
        System.out.println("m2方法被执行...");
    }

    public void m1() {
        class Inner02 { // 局部内部类
            public void f1() {
                System.out.println("n1=" + n1);
                m2();
            }
        }
        Inner02 inner02 = new Inner02();
        inner02.f1();
    }

    {
        class Inner03 {
            public void f2() {
                System.out.println("f2方法被执行...");
            }
        }
        Inner03 inner03 = new Inner03();
        inner03.f2();
    }
}

5.局部内部类不能添加访问修饰符,因为它本质上就是一个局部变量,且仍然是一个类。

局部变量是不能使用修饰符的,只有属性可以。但是可以使用final修饰,因为局部变量也可以使用final,当使用final修饰局部内部类后,表示该局部内部类不能被继承,是一个最终类。

6.外部其它类不能访问局部内部类,因为局部内部类的地位,是一个局部变量

7.如果外部类和局部内部类的成员重名时,默认遵循就近原则;

如果想访问外部类的成员,就要使用 外部类名.this.成员去访问

public class LocalInnerClass {
    public static void main(String[] args) {
        Outer02 outer02 = new Outer02();
        // Outer02.this 本质就是外部类的对象
        // 即:哪个对象调用了局部内部类所在的m1方法,Outer02.this就是哪个对象

        System.out.println("Outer02 hashCode=" + outer02); // 4554617c
        outer02.m1();
    }
}

class Outer02 {
    private int n1 = 100;

    private void m2() {
        System.out.println("m2方法被执行...");
    }

    public void m1() {
        class Inner02 { // 局部内部类
            private int n1 = 900;

            public void f1() {
                // Outer02.this 本质就是外部类的对象
                // 即:哪个对象调用了局部内部类所在的m1方法,Outer02.this就是哪个对象
                System.out.println("Outer02.this hashCode=" + Outer02.this);// 4554617c
                System.out.println("n1=" + n1 + " 外部类的n1=" + Outer02.this.n1);
                m2();
            }
        }
        Inner02 inner02 = new Inner02();
        inner02.f1();
    }
}

三、匿名内部类(重要)

(一)基本介绍

定义:匿名内部类是定义在外部类的局部位置,比如方法、代码块中,并且没有类名。

匿名内部类特点:

  1. 本质是类
  2. 是一个内部类
  3. 该类没有名字(代码中虽然无法看到名字,但实际上JVM会给它分配一个名字)
  4. 同时还是一个对象

基本语法:

new 类或接口(参数列表){
    类体
};

(二)基于接口的匿名内部类

public class AnonymousInnerClass {
    public static void main(String[] args) {
        Outer04 outer04 = new Outer04();
        outer04.method();
    }
}

class Outer04 {
    private int n1 = 10;

    public void method() {
        // 基于接口的匿名内部类
        // 1.需求:想使用IA接口,并创建对象
        // 2.传统方式:写一个类,实现该IA接口,并创建对象
        // 3.但是创建的类只是使用一次,后面不再使用,有些浪费和繁琐
        // 4.可以使用匿名内部类来简化开发
//        Tiger tiger = new Tiger();
//        tiger.cry();

        // 5.我们知道,接口是不能被new的,但是后面的{}里面的内容,相当与实现了接口中的方法
        // 6.tiger的编译类型:IA
        // 7.tiger的运行类型:就是匿名内部类,系统分配的Outer04$1
        /*
         * 底层是会创建一个类 Outer04$1 实现IA接口,即:
           class Outer04$1 implements IA {
               @Override
               public void cry() {
                   System.out.println("老虎叫唤...");
               }
           }
         */
        // 8.JDK底层在创建匿名内部类 Outer04$1,立即就创建了 Outer04$1对象
        //  并且把地址返回给tiger后,该匿名内部类Outer04$1 就立即消失了
        // 9.匿名内部类只能使用一次,但是tiger是一个对象,可以反复调用
        IA tiger = new IA() {
            @Override
            public void cry() {
                System.out.println("老虎叫唤...");
            }
        };
        // 使用getClass()获取对象的运行类型:
        System.out.println("tiger的运行类型="+tiger.getClass()); // Outer04$1
        tiger.cry();
        tiger.cry();
        tiger.cry();
    }
}

interface IA {
    void cry();
}

/*
传统方式:定义类实现IA接口:
class Tiger implements IA {
    @Override
    public void cry() {
        System.out.println("老虎叫唤...");
    }
}*/

(三)基于类的匿名内部类

public class AnonymousInnerClass {
    public static void main(String[] args) {
        Outer04 outer04 = new Outer04();
        outer04.method();
    }
}

class Outer04 {
    private int n1 = 10;

    public void method() {
        // 基于类的匿名内部类
        // 分析:
        // 1.father的编译类型:Father
        // 2.father的运行类型:系统按照顺序分配的 Outer04$2
        // 3.底层会创建匿名内部类:
        /*
            class Outer04$2 extends Father{
                @Override
                public void test() {
                    System.out.println("匿名内部类重写了test方法...");
                }
            }
         */
        // 4.同时也直接返回了 匿名内部类 Outer04$2的对象,即:father
        // 5.注意:("jack")参数列表会传递给Father构造器
        Father father = new Father("jack") {
            @Override
            public void test() {
                System.out.println("匿名内部类重写了test方法...");
            }
        };

        System.out.println("father对象的运行类型:" + father.getClass()); // Outer04$2
        father.test(); // 匿名内部类重写了test方法...
        father.test(); // 匿名内部类重写了test方法...
        father.test(); // 匿名内部类重写了test方法...

        // 6.注意:如果new Father("jack")后面没有{},那么father的运行类型就是Father
        Father father1 = new Father("jack");
        System.out.println("father1对象的运行类型:" + father1.getClass()); // Father


//-----------------------------------------------------------------------------------


        // 基于抽象类的匿名内部类
        // 1.animal编译类型:Animal
        // 2.animal的运行类型:系统按照顺序分配的 Outer04$3
        // 3.底层会创建匿名内部类:
        /*
         * 底层是会创建一个类 Outer04$3 实现IA接口,即:
           class Outer04$3 implements Animal {
               @Override
               public void eat() {
                   System.out.println("小狗吃骨头...");
               }
           }
         */
        Animal animal = new Animal() {
            // 这里要注意:因为Animal中的eat方法是抽象的,所以eat方法必须被实现
            @Override
            void eat() {
                System.out.println("小狗吃骨头...");
            }
        };
        System.out.println("animal的运行类型:" + animal.getClass()); // Outer04$3
        animal.eat(); // 小狗吃骨头...
        animal.eat(); // 小狗吃骨头...
        animal.eat(); // 小狗吃骨头...
    }
}

interface IA {
    void cry();
}

class Father {
    public Father(String name) {
        System.out.println("接收到name=" + name);
    }

    public void test() {}
}

abstract class Animal {
    abstract void eat();
}

(四)注意事项与使用细节

  1. 匿名内部类的语法比较奇特,因为匿名内部类既是一个类的定义,同时它本身也是一个对象。因此从语法上看,它既有定义类的特征,也有创建对象的特征,因此可以调用匿名内部类方法。
  2. 匿名内部类可以直接访问外部类的所有成员,包含私有的。
  3. 匿名内部类不能添加访问修饰符,因为它的地位就是一个局部变量。
  4. 作用域:匿名内部类的作用域仅在定义它的方法或代码块中。
  5. 外部其它类不能访问匿名内部类,因为匿名内部类地位是一个局部变量。
  6. 如果外部类和匿名内部类成员重名时,匿名内部类访问的话,默认就近原则,如果想访问外部类成员,则可以使用(外部类名.this.成员)去访问。
public class AnonymousInnerClassDetail {
    public static void main(String[] args) {
        Outer05 outer05 = new Outer05();
        outer05.f1();
        //外部其他类---不能访问----->匿名内部类
        System.out.println("main outer05 hashcode=" + outer05); // 4554617c
    }
}

class Outer05 {
    private int n1 = 99;

    public void f1() {
        //创建一个基于类的匿名内部类
        //不能添加访问修饰符,因为它的地位就是一个局部变量
        //作用域 : 仅仅在定义它的方法或代码块中
        Person p = new Person() {
            private int n1 = 88;

            @Override
            public void hi() {
                //可以直接访问外部类的所有成员,包含私有的
                //如果外部类和匿名内部类的成员重名时,匿名内部类访问的话,
                //默认遵循就近原则,如果想访问外部类的成员,则可以使用 (外部类名.this.成员)去访问
                System.out.println("匿名内部类重写了 hi方法 n1=" + n1 +
                        " 外部内的n1=" + Outer05.this.n1);
                // 匿名内部类重写了 hi方法 n1=88 外部内的n1=99

                //Outer05.this 就是调用 f1的 对象
                System.out.println("Outer05.this hashcode=" + Outer05.this); // 4554617c
            }
        };


        /**
         * 调用匿名内部类方式一:动态绑定
         */
        p.hi();//动态绑定, 运行类型是 Outer05$1


        /**
         * 调用匿名内部类方式二:直接调用
         */
        //也可以直接调用, 匿名内部类本身也是返回对象
        // class 匿名内部类 extends Person {}
        new Person() {
            @Override
            public void hi() {
                System.out.println("匿名内部类重写了 hi方法,哈哈...");
            }

            @Override
            public void ok(String str) {
                super.ok(str);
            }
        }.ok("jack");
    }
}

class Person {//类

    public void hi() {
        System.out.println("Person hi()");
    }

    public void ok(String str) {
        System.out.println("Person ok() " + str);
    }
}

(五)匿名内部类的最佳实践——当做实参直接传递

将匿名内部类当做实参传递,简洁高效。

代码示例:

传统方式实现接口中的方法:

public class InnerClassExercise01 {
    public static void main(String[] args) {
        f1(new Picture());
        // 传统方式实现接口中的方法...
    }

    public static void f1(IL il) {
        il.show();
    }
}

// 接口
interface IL {
    void show();
}

// 定义类Picture实现IL接口
// 类->实现IL=>编程领域(硬编码)
class Picture implements IL {

    @Override
    public void show() {
        System.out.println("传统方式实现接口中的方法...");
    }
}

使用匿名内部类传参:

public class InnerClassExercise02 {
    public static void main(String[] args) {
        f1(new IL() {
            @Override
            public void show() {
                System.out.println("匿名内部类作为参数传递的方法...");
            }
        });
    }

    public static void f1(IL il) {
        il.show();
    }
}

interface IM {
    void show();
}

        相比与传统定义类实现接口中的方法的硬编码方式,将匿名内部类作为参数传递的方式,更加简洁高效,前提是该抽象方法只使用一次。

(六)小练习

需求:

  1. 有一个铃声接口Bell,里面有个ring方法。
  2. 有一个手机类Cellphone,具有闹钟功能alarmClock,参数是Bell类型
  3. 测试手机类的闹钟功能,通过匿名内部类(对象)作为参数,打印:懒猪起床了
  4. 再传入另一个匿名内部类(对象),打印:小伙伴上课了

代码实现:

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

        CellPhone cellPhone = new CellPhone();

        //1. 传递的是实现了 Bell接口的匿名内部类 InnerClassExercise02$1
        //2. 重写了 ring
        //3. Bell bell = new Bell() {
        //            @Override
        //            public void ring() {
        //                System.out.println("懒猪起床了");
        //            }
        //        }
        cellPhone.alarmClock(new Bell01() {
            @Override
            public void ring() {
                System.out.println("懒猪起床了");
            }
        });

        cellPhone.alarmClock(new Bell01() {
            @Override
            public void ring() {
                System.out.println("小伙伴上课了");
            }
        });
    }
}

interface Bell { //接口
    void ring();//方法
}

class CellPhone {//类

    public void alarmClock(Bell01 bell01) {//形参是Bell接口类型
        System.out.println(bell01.getClass());
        bell01.ring();//动态绑定
    }
}

运行结果:

四、成员内部类

1.成员内部类是定义在外部类的成员位置,并且没有static修饰。

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

class Outer08 { // 外部类
    private int n1 = 10;
    public String name = "张三";

    private void hi() {
        System.out.println("hi()方法...");
    }

    //1.注意: 成员内部类,是定义在外部内的成员位置上
    class Inner08 { // 成员内部类
    }
}

2.成员内部类可以添加任意的访问修饰符,因为它的地位就是一个成员

访问修饰符:public、protected、默认、private

3.成员内部类可以直接访问外部类的所有成员,包含私有的

public class MemberInnerClass01 {
    public static void main(String[] args) {
        Outer08 outer08 = new Outer08();
        outer08.t1();
        // n1 = 10 name = 张三 外部类的n1=10
        // hi()方法...
    }
}

class Outer08 { // 外部类
    private int n1 = 10;
    public String name = "张三";

    private void hi() {
        System.out.println("hi()方法...");
    }

    class Inner08 { // 成员内部类
        public void say() {
            // 4.成员内部类可以直接访问外部类的所有成员,包含私有的
            System.out.println("n1 = " + n1 + " name = " + name);
            hi();
        }
    }

    public void t1() {
        Inner08 inner08 = new Inner08();
        inner08.say();
    }
}

4.作用域:成员内部类的作用域为整个类体

        成员内部类的作用域和外部类的其他成员一样,为整个类体。

        外部类方位成员内部类:在外部类的成员方法中,创建成员内部类对象,再调用相关的方法。

public class MemberInnerClass01 {
    public static void main(String[] args) {
        Outer08 outer08 = new Outer08();
        outer08.t1();
        // n1 = 10 name = 张三 外部类的n1=10
        // hi()方法...
        // 400.56
    }
}

class Outer08 { // 外部类
    private int n1 = 10;
    public String name = "张三";

    private void hi() {
        System.out.println("hi()方法...");
    }

    class Inner08 { // 成员内部类
        private double salary = 400.56;

        private void say() {           
            System.out.println("n1 = " + n1 + " name = " + name);
            hi();
        }
    }

    // 3.外部类访问成员内部类:
    // 说明:在外部类的成员方法中创建成员内部类对象,再使用相关的方法
    public void t1() {
        Inner08 inner08 = new Inner08();
        inner08.say();
        System.out.println(inner08.salary);
    }
}

5.外部其它类访问成员内部类的两种方式

  • 方式一:new 成员内部类(); 将成员内部类当做一个普通的成员来访问,即:对象.成员
  • 方式二:在外部类中定义一个方法,返回一个成员内部类实例
public class MemberInnerClass01 {
    public static void main(String[] args) {
        // 外部其它类访问成员内部类的两种方式
        // 方式一:new Inner08(); 将成员内部类当做一个普通的成员来访问,即:对象.成员
        Outer08 outer08 = new Outer08();
        Outer08.Inner08 inner08 = outer08.new Inner08();
        inner08.say();

        // 方式二:在外部类中定义一个方法,返回一个Inner08实例
        Outer08.Inner08 inner08Instance = outer08.getInner08Instance();
        inner08Instance.say();
    }
}

class Outer08 { // 外部类
    private int n1 = 10;
    public String name = "张三";

    private void hi() {
        System.out.println("hi()方法...");
    }

    public class Inner08 { // 成员内部类
        private double salary = 400.56;

        public void say() {
            System.out.println("n1 = " + n1 + " name = " + name);
            hi();
        }
    }

    // 在外部类中定义一个方法,返回一个Inner08实例
    public Inner08 getInner08Instance() {
        return new Inner08();
    }
}

运行结果:

6.外部类和成员内部类的成员重名访问规则

        如果外部类和成员内部类的成员重名时,成员内部类访问的时候,默认就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问

class Outer08 { // 外部类
    private int n1 = 10;
    public String name = "张三";

    private void hi() {
        System.out.println("hi()方法...");
    }

    public class Inner08 { // 成员内部类
        private double salary = 400.56;
        private int n1 = 66;

        public void say() {
            // 6.如果外部类和成员内部类的成员重名时,成员内部类访问的时候,默认就近原则,
            // 如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问
            System.out.println("n1 = " + n1 + " name = " + name +
                    " 外部类的n1=" + Outer08.this.n1);
            hi();
        }
    }
}

五、静态内部类

1.静态内部类是定义在外部类的成员位置,并且有static修饰

class Outer01{
    private int n1 = 10;
    private static String name = "张三";

    static class Inner10{ // 静态内部类

    }
}

2.可以添加任意访问修饰符,因为它的地位就是一个成员

访问修饰符:public、protected、默认、private

class Outer01{
    private int n1 = 10;
    private static String name = "张三";

    public static class Inner10{ // 静态内部类

    }
}

3.可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员

class Outer01 {
    private int n1 = 10;
    private static String name = "张三";

    private static void m1() {
        System.out.println("外部类的静态方法被执行...");
    }

    public static class Inner10 { // 静态内部类
        public void say() {
            System.out.println(name);
            m1();
        }
    }
}

4.作用域:同其他的成员一样,为整个类体

外部类访问静态内部类:要先创建对象,再访问

public class StaticInnerClass01 {
    public static void main(String[] args) {
        Outer10 outer10 = new Outer10();
        outer10.t1();
        // 张三
        // 外部类的静态方法被执行...
    }
}

class Outer10 {
    private int n1 = 10;
    private static String name = "张三";

    private static void m1() {
        System.out.println("外部类的静态方法被执行...");
    }

    public static class Inner10 { // 静态内部类
        public void say() {
            System.out.println(name);
            m1();
        }
    }

    public void t1(){
        Inner10 inner10 = new Inner10();
        inner10.say();
    }
}

5.外部其他类访问静态内部类的三种方式

public class StaticInnerClass01 {
    public static void main(String[] args) {
        // 外部其他类 使用静态内部类
        // 方式一:
        // 静态内部类,是可以通过类名直接访问(前提是满足访问权限)
        Outer10.Inner10 inner10 = new Outer10.Inner10();
        inner10.say();
        System.out.println("-------------------");

        // 方式二:
        // 编写一个方法,可以返回静态内部类的对象实例.
        Outer10 outer10 = new Outer10();
        Outer10.Inner10 inner101 = outer10.getInner10();
        inner101.say();

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

        // 方式三:
        // 外部类.静态方法
        Outer10.Inner10 inner10_ = Outer10.getInner10_();
        inner10_.say();
    }
}

class Outer10 {
    private int n1 = 10;
    private static String name = "张三";

    private static void m1() {
        System.out.println("外部类的静态方法被执行...");
    }

    public static class Inner10 { // 静态内部类
        public void say() {
            System.out.println(name);
            m1();
        }
    }

    public Inner10 getInner10() {
        return new Inner10();
    }

    public static Inner10 getInner10_() {
        return new Inner10();
    }
}

6.如果外部类和静态内部类的成员重名访问规则

        如果外部类和静态内部类的成员重名时,静态内部类访问的时候,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.成员)去访问。

public class StaticInnerClass01 {
    public static void main(String[] args) {
        Outer10 outer10 = new Outer10();
        outer10.t1();
        // 静态内部类 name=李四 外部类 name=张三
        // 静态内部类的静态方法被执行...
        // 外部类的静态方法被执行...
    }
}

class Outer10 {
    private int n1 = 10;
    private static String name = "张三";

    private static void m1() {
        System.out.println("外部类的静态方法被执行...");
    }

    public static class Inner10 { // 静态内部类
        private static String name = "李四";

        private static void m1() {
            System.out.println("静态内部类的静态方法被执行...");
        }

        public void say() {
            System.out.println("静态内部类 name=" + Inner10.name +
                    " 外部类 name=" + Outer10.name);
            m1(); // 或者是Inner10.m1();
            Outer10.m1();
        }
    }

    public void t1() {
        Inner10 inner10 = new Inner10();
        inner10.say();
    }
}

7.小练习

判断下面代码的输出结果:

public class InnerClassExercise {
    public static void main(String[] args) {
        Test t = new Test();
        Test.Inner r = t.new Inner();// 5
        System.out.println(r.a);// 5
    }
}

class Test {// 外部类
    public Test() {// 构造器
        Inner s1 = new Inner();
        s1.a = 10;
        Inner s2 = new Inner();
        System.out.println(s2.a);
    }

    class Inner { // 成员内部类
        public int a = 5;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2195138.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

leetcode-42. 接雨水 单调栈

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例 1: 输入:height [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表…

Chrome浏览器调用ActiveX控件--allWebOffice控件

背景 allWebOffice控件能够实现在浏览器窗口中在线操作文档的应用(阅读、编辑、保存等),支持编辑文档时保留修改痕迹,支持书签位置内容动态填充,支持公文套红,支持文档保护控制等诸多办公功能,本…

vim编辑器安装,并修改配置使其默认显示行数

centOS默认是未安装vim编辑器的,而vim编辑器相比vi编辑器更易用一些,如需使用vim编辑器,需要进行安装。 1.需要先配置本地yum源,参见如下链接: 点击查看如何配置本地yum源 2.安装vim编辑器,并修改配置。…

滑动窗口_找出字符串中所有字母异位词、串联所有单词的子串_C++

滑动窗口_找出字符串中所有字母异位词、串联所有单词的子串_C 1. 题目解析2. 算法分析3. 代码实现4. 举一反三:串联所有单词的子串 1. 题目解析 leetcode链接:https://leetcode.cn/problems/VabMRr/ 给定两个字符串 s 和 p,找到 s 中所有 p …

helm 测试安装redis

helm search repo redis # 搜索redis的chart helm show readme bitnami/redis # 展示安装相关文档(readme文件) 拉取指定版本的安装包(chart) helm pull bitnami/redis --version 17.4.3 解压安装包 tar -xf redis-17.4.3.tgz …

Vue3 动态路由实现的一种方法

动态路由 目的: 根据服务器传回来的数据动态的注册路由信息,登录用户的角色不同生成的菜单不同 使用插件做动态路由的好处: 路由页面增加或者减少时,只需要增加或减少相关的路由文件,不需要再修改代码 服务器返回的信…

POI数据的处理与分析

POI概念 POI(Point of Interest,兴趣点)数据指的是地理空间数据中的一类,表示某一具体地点或位置的信息。通常,这些数据包含位置坐标(经纬度)、名称、地址、类别和其他相关信息。POI 数据广泛应…

毕业设计 深度学习水果识别

文章目录 1 前言2 开发简介3 识别原理3.1 传统图像识别原理3.2 深度学习水果识别 4 数据集5 部分关键代码5.1 处理训练集的数据结构5.2 模型网络结构5.3 训练模型 6 识别效果 1 前言 Hi,大家好,这里是丹成学长,今天做一个 基于深度学习的水果…

算法剖析:双指针

文章目录 双指针算法一、 移动零1. 题目2. 算法思想3. 代码实现 二、 复写零1. 题目2. 算法思想3. 代码实现 三、 快乐数1. 题目2. 算法思想3. 代码实现 四、 盛水最多的容器1. 题目2. 算法思想3. 代码实现 五、有效三角形的个数1. 题目2. 算法思想3. 代码实现 六、 和为 s 的两…

【EXCEL数据处理】000020 案例 保姆级教程,附多个操作案例。EXCEL使用表格。

前言:哈喽,大家好,今天给大家分享一篇文章!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 【EXCEL数据处理】000020 案例 保姆级教程,附多个操作案例。…

【强训笔记】day27

NO.1 代码实现&#xff1a; #include<iostream>using namespace std;int n,m; int main() {cin>>n>>m;long long retn;for(int i0;i<m-1;i)retret*(n-1)%109;cout<<ret<<endl;return 0; }NO.2 思路&#xff1a;bfs遍历实现&#xff0c;dis…

Android架构--MVVM

一、开发架构 是什么&#xff1f; 二、Android开发中的架构 具体到Android开发中&#xff0c;开发架构就是描述 视图层、逻辑层、数据层 三者之间的关系和实施&#xff1a; 视图层&#xff1a;用户界面&#xff0c;即界面的展示、以及交互事件的响应。 逻辑层&#xff1a;为…

IL2CPP和Mono的区别

Mono 是一种开源的跨平台 .NET 框架实现&#xff0c;能够执行 C# 代码。Unity 使用 Mono 来处理 C# 脚本&#xff0c;并通过 JIT&#xff08;Just-In-Time&#xff09;即时编译器将托管代码转换为本地机器代码&#xff0c;随后在目标平台上执行 IL2CPP 代表 Intermediate Lang…

《业务三板斧:定目标、抓过程、拿结果》读书笔记3

关于目标&#xff0c;关键是共识目标&#xff1a; 为什么不是共识目标&#xff0c;而是共信目标&#xff1f; 共识目标是指管理者通过沟通&#xff0c;让所有团队成员就目标以及实现目 标的方法达成一致。当个人与组织、个人与个人之间出现“路径选择 差异”的时候&#xff0c;…

算法专题四: 前缀和

目录 1. 前缀和2. 二维前缀和3. 寻找数组的中心下标4. 除自身以外数组的乘积5. 和为k的子数组6. 和可被K整除的子数组7. 连续数组8. 矩阵区域和 博客主页:酷酷学!!! 感谢关注~ 1. 前缀和 算法思路: 根据题意, 创建一个前缀和数组, dp[i] dp[i -1] arr[i], 再使用前缀和数组,…

Go编译为可执行文件

在window下打包成其他系统可运行的文件 1.在window下打包成window下可执行文件 在项目main.go同级目录下&#xff0c;逐条执行以下命令 set CGO_ENABLED0 set GOOSwindows set GOARCHamd64 go build -o main-windows.exe main.go 2.在window下打包成linux 在项目main.go同级目…

Android Codec2 CCodec(十六)C2AllocatorGralloc

这一篇文章我们一起来瞧瞧2D&#xff08;Graphic&#xff09; buffer分配器C2AllocatorGralloc是如何工作的。 1、GraphicBuffer 在Android系统中&#xff0c;GraphicBufferAllocator和GraphicBufferMapper是与图形缓冲区&#xff08;Graphic Buffers&#xff09;管理相关的重…

Python爬取b站视频:验证cookie是否有效

具体代码 import requestsheaders {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0,Referer: https://www.bilibili.com/,Origin: https://www.bilibili.com } def readCooki…

Nginx02-安装

零、文章目录 Nginx02-安装 1、Nginx官网 Nginx官网地址&#xff1a;http://nginx.org/ 2、Nginx下载 &#xff08;1&#xff09;Nginx下载 下载页地址&#xff1a;http://nginx.org/en/download.html &#xff08;2&#xff09;更老版本下载 下载页地址&#xff1a;http…

四、链表————相关算法探讨(持续更新中)

链表中相关算法探讨 前言一、移除链表元素1.1 思路分析1.2 解法探讨1.2.1 直接删除1.2.2 创建虚拟头节点来删除1.2.3 递归版删除 二、反转列表2.1 思路分析2.2 做法2.2.1 创建新链表方式2.2.2 双指针法2.2.3 递归法 三、两两交换链表中的节点3.1 思路分析3.2 解法探讨3.2.1 不使…