Java---内部类

Java---内部类

内部类的概念

内部类就是一个类内部包含另一个类

分类:

  1. 成员内部类
  2. 局部内部类(包含匿名内部类)

格式:

修饰符 class 外部类名称

{

修饰符 class 内部类名称

{

//

}

}

注意:内用外,随意访问;外用内,需要内部类对象.

image-20230511100502621

代码示例

public class Body {
    private String name;

    public class Heart {
        public void show() {
            System.out.println("名字是" + name);//内部随便访问外部.即使外部类是私有的
        }

        public void method() {
            System.out.println("我是内部类");
        }
    }

    public void methodwai() {//外部类方法
        System.out.println("我是外部类方法");
    }

    public Body(String name) {
        this.name = name;
    }

    public Body() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

使用成员内部类

1.间接方法

2.直接方法

外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();

image-20230511101750815

代码示例

间接方法

内部类

public class Body {
    private String name;

    public class Heart {


        public void method() {
            System.out.println("我是内部类方法");
            System.out.println("名字是" + name);//内部随便访问外部.即使外部类是私有的
        }
    }

    public void methodwai() {//外部类方法
        System.out.println("我是外部类方法");
        new Heart().method();//再内部类方法里面调用内部类
    }

    public Body(String name) {
        this.name = name;
    }

    public Body() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Main方法

public class Main {
    public static void main(String[] args) {
        Body one =new Body();
        one.methodwai();//调用外部类方法,里面含有内部类对象
    }
}

直接使用

内部类

public class Body {
    private String name;

    public class Heart {


        public void method() {
            System.out.println("我是内部类方法");
            System.out.println("名字是" + name);//内部随便访问外部.即使外部类是私有的
        }
    }

    public void methodwai() {//外部类方法
        System.out.println("我是外部类方法");
        new Heart().method();//再内部类方法里面调用内部类
    }

    public Body(String name) {
        this.name = name;
    }

    public Body() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Main方法

public class Main1 {
    public static void main(String[] args) {
        //使用外部类创建内部类对象来使用内部类
        //第一个new body()实际上就是一个构造方法
        Body.Heart one = new Body("小黑").new Heart();
        one.method();
    }


}

内部类的同名访问

如果出现了重名现象那么格式是,外部类名称.this.外部类成员变量名.

image-20230512090303175

代码示例

内部类

public class Outher {
    int num = 10;

    public class Inter {
        int num = 20;

        public void show() {
            int num = 30;
            System.out.println(num);//就近原则成员变量
            System.out.println(this.num);//调用本类当中的变量
            System.out.println(Outher.this.num);//类名称.this.变量名
        }

    }
}

Main方法

public class Main {
    public static void main(String[] args) {
        //创建内部类
        Outher.Inter one = new Outher().new Inter();
        //外部类名称.内部类名称 变量名 = new 外部类名称().new 内部类名称();
        one.show();

    }
}

局部内部类定义

如果一个类是定义在一个方法内部的,那么这就是一个局部内部类.

"局部":只有当前所属的方法才能使用它,出了这个方法就不能用了

注意事项:

修饰符

public>protected>(default)>private

定义一个类的时候,权限修饰符

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

image-20230512091137731

image-20230512091155394

代码示例

局部内部类

public class Outher {
    public void method() {//只有这个成员方法才能访问这个局部内部类

        class Inther {//局部内部类
            int num=10;//成员变量

            public void show() {//局部内部类方法
                System.out.println(num);
            }

        }
        Inther one = new Inther();
        one.show();


    }
}

Main方法

public class Main {
    public static void main(String[] args) {
        Outher one =new Outher();//创建外部类对象
        one.method();//调用成员方法


    }
}

局部内部类的final问题

局部内部类:如果希望访问在方法的局部变量:那么这个局部变量必须是[有效final的]

原因:

  1. new出来的对象在堆内存中

  2. 局部变量是跟着方法走的,在栈内存当中

  3. 方法结束运行之后,会立刻出栈,局部变量就会消失

  4. 但是new出来的对象会在堆当中一直存在,直到垃圾回收为止

    image-20230512092958129

代码示例

内部类

public class Outher {
    public void method() {
        int num = 30;//或者加上final
//        num=20;//不可改变num的值
        class Inner {
            public void show() {
                System.out.println(num);//直接访问局部变量,局部变量必须是有效final的
            }
        }
    }
}

匿名内部类

如果接口的实现类(或者是父类的子类)只需要使用一次

那么这种群概况就可以省略该类的定义,而改为使用(匿名内部类)

格式:

接口名称 对象名 = new 接口名称(){

//覆盖重写所有的方法

};

image-20230512094743822

代码示例

接口

public interface Interface {
    public abstract void methd();//抽象方法
}

Main方法

public class Main {
    public static void main(String[] args) {
        Interface one = new Interface() {//匿名内部类,需要重写全部接口当中的全部的抽象方法
            @Override//进行从写接口的方法
            public void methd() {
                System.out.println("匿名内部类重写了方法");
            }
        };//加上;
        one.methd();
    }

}

匿名内部类的注意事项

  1. 匿名内部类,在[创建对象]的时候只能使用唯一的一次

  2. 匿名对象,在[调用方法]的时候,只能调用唯一的一次

  3. 匿名内部类是省略了[实现类/子类名称],但是匿名对象,省略了[对象名称]

    image-20230513102413966

代码示例

接口

public interface Interface {
    public abstract void methd1();//抽象方法
    public abstract void methd2();//抽象方法


}

Main方法

public class Main {
    public static void main(String[] args) {
        //使用匿名内部类创建对象,匿名内部类是省略了类名称而不是对象名
        Interface one = new Interface() {//匿名内部类,需要重写全部接口当中的全部的抽象方法
            @Override//进行从写接口的方法
            public void methd1() {
                System.out.println("匿名内部类重写了方法 1111");
            }

            public void methd2() {
                System.out.println("匿名内部类重写了方法 222");
            }
        };//加上;
        one.methd1();
        one.methd2();
        Interface two = new Interface() {
            @Override
            public void methd1() {
                System.out.println("匿名内部类重写了方法 1111");
            }

            @Override
            public void methd2() {
                System.out.println("匿名内部类重写了方法 222");
            }
        };
        two.methd1();
        two.methd2();

        //下面来使用匿名内部类来创建匿名对象
        //但是匿名对象只能调用唯一一次方法
        new Interface(){

            @Override
            public void methd1() {
                System.out.println("匿名内部类重写了方法 1111");
            }

            @Override
            public void methd2() {
                System.out.println("匿名内部类重写了方法 2222");
            }
        }.methd1();
        new Interface(){

            @Override
            public void methd1() {
                System.out.println("匿名内部类重写了方法 1111");
            }

            @Override
            public void methd2() {
                System.out.println("匿名内部类重写了方法 2222");
            }
        }.methd2();
    }

}

posted @ 2023-05-11 12:13  harper886  阅读(17)  评论(0编辑  收藏  举报