• 访问修饰符你用对了吗


      不知道大家在平时的开发过程中有没有注意到访问修饰符,哈哈哈,有没有懵,在java中有哪些访问修饰符,还记得清吗?今天想分享下访问修饰符的哪些小事。

    一、访问修饰符有哪些

      在java中提到访问修饰符,大家可能都不陌生,但对于访问修饰符我还是想再重申下,这些看似很普通的概念,在多年后的某个瞬间总能激起我们某些想法。

      java中说白了就三种元素:类、方法、属性,由这三种元素组合成了我们平时使用的API,来标识这三种元素的访问权限的字符就是访问修饰符,通俗点理解就是我有一个方法我只想自己自己知道,我不想别人知道那么我给它一个标识private,代表是私有的,那么别人就无法访问了,如果我想让方圆5公里的人知道,我给它个标识protected,那么就只有方圆5公里的人知道。访问修饰符就是来控制类、方法、属性的访问范围的

      在java中有四种访问修饰符,分别是public、protected、default、private。上面说到java中有类、方法、属性,下面看下这几种访问修饰符怎么起作用的。

      先上一张图,让大家有个大体的印象,

    1.1、public  

      public,公开的,公共的。可以修饰类、方法、属性。在修饰类的时候,一个.java文件中只能有一个类是公共的,且和.java文件同名;重点看下最后这句话,

      看到了吧,在idea中给的提示很明确,Teacher是公共的(public),应该声明到一个文件名为Teacher.java的文件中。其实也很容易理解,在一个.java文件中有多个公共的class,是无法区分哪个是主类的,所以在一个.java文件中只能有一个公共的类。遗留一个小问题,在一个public的类中可以有其他修饰符修饰的类吗?后面揭晓。

      public修饰方法和属性,想必不用我多说了,在平时使用的比较多,public修饰方法和属性不受包的限制,在任何包中均可访问

    1.2、protected

      protected,受保护的。可以修饰内部类、方法、属性。这里有个概念是内部类,当然和内部类相对应的就是外部类,所谓内部类就是在一个外部类中的类,外部类就是平时我们写的类,其类名和文件名一样。一个例子如下,

    package com.example.day04;
    /**
    Teacher是外部类
     */
    public class Teacher {
        /**
         * Inner是内部类
         */
        protected class Inner{
            
        }
    }

    重点来看下protected修饰的方法和属性,

    package com.example.day04;
    /**
    Teacher是外部类
     */
    public class Teacher {
        protected String name;
        protected void method(){
            System.out.println(this.name);
        }
    }

    那么name和method()方法可以被哪些类访问呐?看下本包中的类,

    package com.example.day04;
    
    public class TeacherA {
        public static void main(String[] args) {
            Teacher teacher=new Teacher();
            teacher.name="tom";
            teacher.method();
        }
    }

    protected修饰的方法、属性可以被本包中的类访问,再来看下本包中的子类,

    package com.example.day04;
    
    public class TeacherB extends Teacher{
        public static void main(String[] args) {
            TeacherB teacherB=new TeacherB();
            teacherB.name="tom";
            teacherB.method();
        }
    }

    打印结果如下,

    tom
    
    Process finished with exit code 0

    protected修饰的方法、属性可以被本包中的子类访问,再来看下不同包中的类,

    protected修饰的方法、属性不可以被不同包中的类访问,那么不同包的子类呐?

    package cn.example.day04;
    
    import com.example.day04.Teacher;
    
    public class TeacherD extends Teacher {
        public static void main(String[] args) {
            TeacherD teacherD=new TeacherD();
            teacherD.name="tome";
            teacherD.method();
        }
    }

    结果如下,

    tome
    
    Process finished with exit code 0

    protected修饰的方法、属性可以被不同包中的子类访问。

    总结:protected修饰的属性和方法可以被同包中的类、子类访问;可以被不同包的子类访问,不可以被不同包的类访问。

    1.3、default

    这里说default其实不是那么严格,在java中不写访问修饰符,就是default,称为default只为了好记,其实没有“default”这个访问修饰符

    default,默认的访问修饰符。可以用来修饰类、属性、方法。

    有default修饰的类、属性、方法,

    package com.example.day04;
    
    class Address {
        String name;
        void method(){
            System.out.println(name);
        }
    }

    在本包下的类,

    package com.example.day04;
    
    public class AddressA {
        public static void main(String[] args) {
            Address address=new Address();
            address.name="china";
            address.method();
        }
    }

    结果如下,

    china
    
    Process finished with exit code 0

    默认情况下的访问修饰符,在本包下的类是可以访问的。看下在本包下的子类,

    package com.example.day04;
    
    public class AddressB extends Address{
        public static void main(String[] args) {
            Address address=new Address();
            address.name="china";
            address.method();
        }
    }

    看代码正常编译未出错,肯定是可以的。

    默认情况下的访问修饰符,在本包下的子类是可以访问的。不同包下的类和子类,这里不再一一列出例子了,直接给出下面的结论,

    默认情况下的访问修饰符,在不同包下的类、子类都是不可以访问的默认修饰符修饰的类、属性、方法。

    总结,默认情况下的访问修饰符,在本包下的类、子类是可以访问的;在不同包下的类、子类都是不可以访问

    1.4、private

    private,私有的。可以修饰类、属性、方法。

    在private修饰类时,不可以修饰外部类,可以修饰内部类。重点看下修饰的属性、方法,这个是我们在平时开发中用的最多的。

    这里有一个使用private修饰的属性、方法,

    package com.example.day04;
    
    public class Person {
    
        private String name;
        private void method(){
            System.out.println(name);
        }
        private class A{
            
        }
    }

    看下图,在本包中,

    private修饰的属性、方法在本包中的类中是无法访问的。看下在本包的子类呐?

    private修饰的属性、方法在本包的子类中是无法访问的。

    总结,private修饰的属性、方法在本包中的类、子类是无法访问的,在不同包的类、子类是无法访问的。

    二、一些小趣事

    上面说了很多乏味的基础知识,在日常的开发中你可能都意识不到天天在用。下面看一下几个有意思的小问题。

    2.1、一个public修饰的类中可以有其他类吗

    我们知道一个public修饰的类的类名和.java文件名是一样的,那么在这个类中还可以有其他类吗?

    从上图中可以看到,一个public修饰的类中仅可以有默认修饰符修饰的类,protected、private修饰的均不可以,public修饰的也不可以哦。

    2.2、protected方法存在的意义

      protected修饰的方法可以在本包类、子类、不同包的子类访问。这种方法存在的意义是什么呐?在继承中,子类可以访问父类的protected方法,既然是继承了,那么没继承的类便不可访问,protected很好的诠释了继承的意义。平时开发中使用protected方法是在抽象类中的抽象方法。

    package com.example.day04;
    
    /**
     * 抽象的Car工厂
     */
    public abstract class AbstractCarFactory {
        protected abstract void generateCar();
    }

    那么子类需要去覆盖该抽象方法,非子类不需要覆盖该方法,所以这个方法是protected访问修饰符修饰的。有人会说是public修饰的可以吗?当然可以,但是权限肯定是越小越好啊,

    package com.example.day04;
    
    public class BiyadiCarFactroy extends AbstractCarFactory{
        @Override
        public void generateCar() {
            System.out.println("generate biyadi car");
        }
    }

    在子类中还可以改变覆盖方法的访问修饰符。

    2.3、有了private为什么还要public

    在开发中写的最多的可能就是类似下面的实体类,

    package com.example.day04;
    
    public class Address {
        private String name;
        private String code;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getCode() {
            return code;
        }
        public void setCode(String code) {
            this.code = code;
        }
    }

      Address类中属性是private,而getXXX和setXXX方法是public,这是为了保护属性,方式使用实例.属性的方式进行设置/获取值,而是通过其提供的setXXX/getXXX方法来设置/获取值。通过方法的方式,可以在设置值的过程中对值进行校验、判断等操作,而直接通过实例.属性的方式则无法完成上面的操作,只不过在日常的开发中,都是直接赋值,没有进行校验、判断等其他操作而已。例下方,

      public void setName(String name) {
            System.out.println("设置name的值为:"+name);
            if(name.equals("china")){
                this.name = name;
            }
            System.out.println("设置完成");
        }

    2.4、子类无法访问父类的私有属性吗

    上面我们知道在子类中是无法访问父类的私有属性的,因为属性是私有的即使子类也是无法访问的。但我依然可以访问到,

    我们直接无法访问到name属性,但是我们可以通过其暴露的getXXX方法啊。

    三、总结

      本文分享了在平时开发中很容易忽略的一个点,就是访问修饰符,我们平时用的最多的要属public、private,但是为什么要使用,这样使用的好处是什么。有人说一个项目中都是自己项目内的人,没必要考虑访问修饰符,我直接都用public不是更好,这样也没错,但是这样带来的后果是没有任何的访问限制,类比生活中人人都是想怎么干就怎么干,想去什么地方就去什么地方,这样岂不是没了规则,这个社会是不是无法正常运转了。到了程序中虽然没有那么严重,但是遵循一定的原则,对代码的整体设计后续的扩展性也是好的。本文只是想做个引子,提醒小伙伴们日常的开发中多思考,多尝试。

  • 相关阅读:
    css3-文本新增属性
    css3新增的伪类和伪元素
    git小记
    css3笔记
    jQuery(三)
    jQuery笔记(二)
    <转>HTML、CSS、font-family:中文字体的英文名称
    jQuery笔记
    DOM父节点、子节点例子
    DOM之节点类型加例子
  • 原文地址:https://www.cnblogs.com/teach/p/16295605.html
Copyright © 2020-2023  润新知