Java权限修饰符、内部类(尤其注意匿名内部类)

这一块的内容主要是有关	权限修饰符、内部类的概述。

权限修饰符

在这里插入图片描述

  • 同一个类下:
public class PowerDemo1{

    public String name = "张三";
    protected int age = 21;
    boolean flag = true;
    private String id = "001";

    public static void main(String[] args) {

        PowerDemo1 powerDemo1 = new PowerDemo1();
        System.out.println(powerDemo1.name);
        System.out.println(powerDemo1.age);
        System.out.println(powerDemo1.flag);
        System.out.println(powerDemo1.id);

    }
}
//张三
//21
//true
//001
  • 同一个包子类、其他类
class Power{
    public String name = "张三";
    protected int age = 21;
    boolean flag = true;
    private String id = "001";
}

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

        Power power = new Power();
        System.out.println(power.name);
        System.out.println(power.age);
        System.out.println(power.flag);
        //Error:(18, 33) java: id可以在com.bigdata.shujia14.Power中访问private
//        System.out.println(power.id);
    }
}
//张三
//21
//true
  • 不同包的子类
public class PowerTest1 extends PowerDemo1 {
    public static void main(String[] args) {
        PowerTest1 powerTest1 = new PowerTest1();
        System.out.println(powerTest1.name);    //public修饰的
        System.out.println(powerTest1.age);     //protected修饰的
    }
}
//张三
//21
  • 不同包的其他类
public class PowerTest1 extends PowerDemo1{
    public static void main(String[] args) {
        PowerDemo1 powerDemo1 = new PowerDemo1();
        System.out.println(powerDemo1.name);//public修饰的
    }
}
//张三
  • 类及其成员修饰符
    权限修饰符:private、默认的、protected、public
    状态修饰符:static、final
    抽象修饰符:abstract

类:
权限修饰符:默认的、public
状态修饰符:final
抽象修饰符:abstract
最常用的是public
在这里插入图片描述

成员变量:
权限修饰符:private、默认的、protected、public
状态修饰符:static、final
最常用的是public

在这里插入图片描述

构造方法:
权限修饰符:private、默认的、protected、public
最常用的是public
在这里插入图片描述

成员方法:
权限修饰符:private、默认的、protected、public
状态修饰符:static、final
抽象修饰符:abstract
最常用的是public
在这里插入图片描述

内部类

  • 把类定义在其他类的内部,这个类就被称为内部类
    举例:在类A中定义了一个类B,类B就是内部类
  • 内部类的访问特点:
    • 内部类可以访问外部类的成员,包括私有
    • 外部类如果想要访问内部类的成员,就必须要创建对象

举例:
内部类Inner访问外部类Outer的变量,可以直接访问
外部类Outer访问内部类Inner的成员,需要创建对象,并由一个新的方法show2()调用

在这里插入图片描述

  • 内部类的位置:
    按照内部类在类中定义的位置不同,分为如下两种格式
    - 成员位置(成员内部类)
    - 局部位置(局部内部类)

成员位置、局部位置 举例:
在这里插入图片描述

  • 成员内部类:
    • 内部类可以访问外部类的成员,包括私有
    • 如何创建对象呢
      外部类名.内部类名 对象名 = new 外部类名.new 内部类名
class Outer3{
    private int num = 20;

    class Inner{
        public void show(){
            System.out.println(num);
        }
    }
}

public class InnerClassDemo3 {
    public static void main(String[] args) {
        //想要访问内部类的show()方法,就必须要创建Inner对象
//        Inner inner = new Inner();
//        inner.show();

        //正确创建内部类对象的格式:
        Outer3.Inner i = new Outer3().new Inner();
        i.show();
    }
}
//20
  • 成员内部类常见修饰符:
    private:为了保证数据的安全性
    static:为了方便访问数据
    注意事项:静态内部类访问的外部数据必须由静态修饰
class Outer4{
    //局部变量
    private int num = 10;
    private static int num2 = 20;

    //成员内部类被静态修饰    访问的局部变量也只能是静态的
    public static class Inner4{
        public void show(){
//            System.out.println(num);
            System.out.println(num2);
        }

        public static void show2(){
//            System.out.println(num);
            System.out.println(num2);
        }
    }
}

public class InnerClassDemo4 {
    public static void main(String[] args) {
        Outer4.Inner4 i = new Outer4.Inner4();
        i.show();//20
        i.show2();//20

        //另一种创建内部类的方式,当成员变量被静态修饰后,访问的格式如下:
        //外部类名.内部类名 对象名 = new   外部类名.内部类名()
        Outer4.Inner4 i1 = new Outer4.Inner4();
        i1.show();//20
        i1.show2();//20

        //调用show2()的另一种方式
        Outer4.Inner4.show2();//20
    }
}

一道小题目来加深理解外部类和内部类之间的一些小细节
在控制分别输出:30,20,10
class Outer {
public int num = 10;
class Inner {
public int num = 20;
public void show() {
int num = 30;
System.out.println(?);
System.out.println(??);
System.out.println(???);
}
}
}

  • 注意:
    • 内部类和外部类之间不存在继承关系,既然没有继承关系,那就没有super关键字
    • 通过外部类名限定this对象 Outer5.this

这里是成员内部类

class Outer5{

    public int num = 10;

    class Inner5{

        public int num = 20;

        public void show(){
            int num = 30;
            System.out.println(num);//30
            System.out.println(this.num);//20
            System.out.println(Inner5.this.num);//20
            System.out.println(new Outer5().num);//10
            //Outer5.this   这里面的this指的就是Outer5
            System.out.println(Outer5.this.num);//10
            
        }
    }
}

public class InnerClassDemo5 {
    public static void main(String[] args) {
        Outer5.Inner5 i = new Outer5().new Inner5();
        i.show();
    }
}
  • 局部内部类:
    • 可以直接访问外部类的成员
    • 可以创建内部类对象,通过调用内部类的方法,来使用局部内部类的功能
class Outer6{
    private int num = 100;
    public void show(){
        int num2 = 200;
        class Inner6{
            public void show1(){
                System.out.println(num);
                System.out.println(num2);//本来这地方应该报错的,但这里jdk在1.8之后自动添加了一个final,
                // 看下面的代码可以很好的理解,num2被调用了两次,但实际上,用了一次之后,就消失了,JVM自动添加了一个final

                /*
                局部内部类访问局部变量必须要被final修饰
                因为局部变量会随着方法的调用完毕而消失,这个时候,
                局部对象并没有立马从堆内存中消失,还要使用那个变量。
                为了让数据还能继续被使用,就用fianl修饰,
                这样,在堆内存里面存储的其实是一个常量值
                 */

            }
        }
        System.out.println(num2);
        Inner6 inner6 = new Inner6();
        inner6.show1();
    }
}

public class InnerClassDemo6 {
    public static void main(String[] args) {
        Outer6 outer6 = new Outer6();
        outer6.show();
    }
}
//200
//100
//200

我们查看了Outer6.class的字节码文件
在这里插入图片描述
发现JVM自动给外部类的成员加上了final关键字,让它可以多次被使用

匿名内部类

  • 就是内部类的简化写法
  • 前提:存在一个类或者接口
    这里的类可以是具体类,也可以是抽象类
  • 格式:new 类名或者接口名(){重写方法;}
  • 本质是:是一个继承了这个类或者实现了这个接口的子类的匿名对象

匿名内部类的简单使用和一些改进 代码举例:

interface Inter{
    public abstract void show();
    public abstract void show2();
}


class Outer7{
    public void fun() {

//        new Inter() {
//            public void show() {
//                System.out.println("show()方法");
//            }
//            public void show2() {
//                System.out.println("这是show2()方法");
//            }
//        }.show2();
//
//        new Inter(){
//            public void show(){
//                System.out.println("这是show()方法");
//            }
//            public void show2(){
//                System.out.println("这是show2()方法");
//            }
//        }.show();

        //问题,如果我这个接口有很多方法,还需要使用匿名内部类的形式就很麻烦
        //怎么改进
        Inter inter = new Inter(){
            public void show() {
                System.out.println("这是show方法");
            }

            public void show2() {
                System.out.println("这是show2方法");
            }
        };
        inter.show();
        inter.show2();
    }
}

public class InnerClassDemo7 {
    public static void main(String[] args) {
        Outer7 outer7 = new Outer7();
        outer7.fun();
    }
}
//这是show方法
//这是show2方法
  • 匿名内部类在开发中的使用
interface Person{
    public abstract void studey();
}

class PersonDemo{
    //接口作为参数的时候,需要的是实现该接口类的对象
    public void fun(Person p){
        p.studey();
    }
}

class Student implements Person{
    @Override
    public void studey() {
        System.out.println("学生学习");
    }
}

public class InnerClassDemo8 {
    public static void main(String[] args) {
        Person p = new Student();
        PersonDemo personDemo = new PersonDemo();
        personDemo.fun(p);//学生学习

        System.out.println("*********使用匿名内部类进行改进********");

        personDemo.fun(
                new Person() {
                    @Override
                    public void studey() {
                        System.out.println("这是匿名内部类的使用");
                    }
                }
        );
    }
}

一个小练习来巩固匿名内部类的使用
按照要求,补齐代码
interface Inter{ void show(); }
class Outer{ //补齐代码 }
class OuterDemo(
public static void main(String[] args){
Outer.method().show();
}
}
要求在控制台输出"HelloWorld"

//通过:Outer.method().show()
//可以看出来     应该method是一个静态方法,因为静态方法直接.show()就使用了show方法
//又因为show方法是在Inter1中的,而Inter1是一个接口,所以method方法的返回值应该是Inter1接口类型
interface Inter1 { void show(); }
class In implements Inter1{
    public void show(){
        System.out.println("HelloWorld");
    }
}

class Outer1{
    public static Inter1 method(){

//        这是没有学习匿名对象的时候可以只有用
//        In in = new In();
//        in.show();
//        return in;

//        学了匿名对象之后
        return new Inter1() {
            @Override
            public void show() {
                System.out.println("HelloWorld");
            }
        };
    }
}

public class InnerClassDemo9 {
    public static void main(String[] args) {
        Outer1.method().show();
    }
}

感谢阅读,我是啊帅和和,一位大数据专业即将大四学生,祝你快乐。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

啊帅和和。

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

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

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

打赏作者

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

抵扣说明:

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

余额充值