JAVA基础 访问控制

今天我们来聊一聊访问控制

什么是访问控制呢?

访问控制就是JAVA中控制类外的程序,能够访问类中的那些的成员。

有些人可能会问了,类的成员变量不是都能在外部访问吗? 其实不是的。

这和现实中一样。我们有很多属性也是不能对外公开的,比如说你的银行卡的卡号和密码,或者说银行存折的余额,女孩的体重,女孩的年龄这些都是不能被访问的。

JAVA中也是一样的,我们的类中的成员不应该被随便就被外界轻易的访问到,甚至被外界破坏掉。
JAVA中使用类封装成员,并不是仅仅为了,把成员集中在一起保存这么简单,它更重要的目的是保护这些成员。

JAVA的4个保护级别

第一种是 pubulic , public级别是最公开的,也就是完全没有限制可以随便的访问
第二种是 private ,它和public相反,它是私有的,也就是完全的私密,外界完全不能访问
第三种是 protected,它是专门用于继承当中的父子类之间
第四种就是默认的控制级别

访问控制

在这里插入图片描述在讲访问控制之前,我们先讲一下包,那么什么是包呢?

包(package)

・在硬盘.上,包是存储多类(.class)的文件夹
・在程序中,组织多类名,避免类名冲突的名称空间
・包的作用,就是分组管理类定义,并避免类名冲突
・Java源代码中,第一行, 一般都要指定当前类所属的包名,
・语法:
・package 包名; 其中 ,包名建议所有字母小写。
・其实, Java中一个类的全名,应该是:包名.类名。
-例如:
在这里插入图片描述
・Java规定:
-任何类的.class文件,必须保存在类中指定的包名文件夹下。
-同一个包中不能保存两个同名的类

package语句

包名也可以有层次结构。定义多层包名,语法:

  • package 顶级包名.子级包名…n级包名;
    -说明,每一级包名使用 “.” 连接。
    -包名层次结构和文件夹层次结构完全对应
    多层包名的一般规范: package 公司或组织的域名.项目名.功能模块名
    例如:
    org.apache.commons.lang
    org.apache 公司域名
    commons 项目名称
    lang 功能模块

再比如:腾讯公司要做一套学生管理系统。 其中包含一个课程管理功能模块:
com.tencent .studentmgt .coursemgt

import语句

・访问类时都需要使用类的全称。如果不写全称,仅用类名,默认只在当前包中寻找。
例如: Scanner类,其实全称: java.util.Scanner

java.util.Scanner sc=new java.util.Scanner(System.in);
//编译正确。但是太繁琐

可以通过import语句先引入类的全称,语法:

  • import类的完全限定名;
    -完全限定名:就是包名.类名

通过import语句引入了类的全称后,在当前源文件中就可以仅使用类名访问了
例如:

import java util. Scanner;
Scanner sc=new Scanner(System.in);
//编译正确。因为已经导入了完全限定的类名

接下来我们直入主题 学习访问控制修饰符

访问控制修饰符

封装的意义

在这里插入图片描述

水果店的功能,无非就是上货,打包,称重,收款等等

现在水果店有2种经营模式:

A:老板当甩手掌柜,客户自己随便取水果、随便称重,随便找零钱。
B:老板帮客户取水果,打包,找零。

第一种经营模式肯定行不通,可能上午开门,下午就倒闭了。

封装的意义

对外提供可调用的、 稳定的功能;
封装内部具体的实现细节, 外界不可访问,这样的好处在于:
-降低出错的可能性,便于维护;
-内部变化,不会影响外部使用;


public和private

●private修饰的成员只能在本类的成员方法中使用
●通常类的成员变量都应该使用private严格控制。只能通过类提供的方法访问。
●private修饰的成员仅是对内使用,如果“公开”会大幅增加维护成本。
●public修饰的成员可以在任何地方使用。
●凡是对外的成员方法要非常的健壮和稳定

封装水果店属性和功能的类

package day07;

/**
 * 封装水果店属性和功能的类
 */
public class Shop {
    
    
        double buying=5.5; //水果的进价5块5一斤
        double price=8; //销量8块一斤
        double total; //销售量(斤数)

        /**
         * 卖水果的方法
         * money 多少钱
         * count 多少斤
         */
         void sale(double money,double count){
    
    
            //累加销量量
            total+=count;
            //输出本次购买的结果
            System.out.println("您购买的水果"+count
                    +"斤水果,收您"+money
                    +"元,找零"+(money-price*count));
      }
}

我们先来测试:如果一个顾客进到店里买水果,他先看了看进价,又看了看售价,感觉卖的太贵了,一气之下把你的售价改成了0.01元,然后给了一百元。

package day07;

public class Test {
    
    
    public static void main(String[] args) {
    
    
        Shop s=new Shop();
        //加入一个顾客来买水果,先看了进价5.5元
        System.out.println(s.buying);
        //又看了看售价8元
        System.out.println(s.price);
        //他愤怒的把售价price改成为0.01
        s.price=0.01;
        //再调用sale方法
        s.sale(100,10);
    }
}

在这里插入图片描述
以上案例可以知道,我们的进价是不能让人轻易的看见或修改,那么怎么解决这个问题呢?
我们来对代码进行修改,让进价不可见,让售价不能修改,也要加上private!

package day07;

/**
 * 封装水果店属性和功能的类
 */
public class Shop {
    
    
       private double buying=5.5; //水果的进价5块5一斤
       private double price=8; //销量8块一斤
        double total; //销售量(斤数)

    /**
     *专门读取price属性的方法
     * 相当于老板可以告诉客人,这水果多少钱,但是客人不知道
     * @return
     */
    public double getBuying() {
    
    
        return buying;
    }
    public double getPrice() {
    
    
        return price;
    }

    /**
         * 卖水果的方法
         * money 多少钱
         * count 多少斤
         */
         void sale(double money,double count){
    
    
            //累加销量量
            total+=count;
            //输出本次购买的结果
            System.out.println("您购买的水果"+count
                    +"斤水果,收您"+money
                    +"元,找零"+(money-price*count));
      }
}

经过修改private 加密,我们可以发现无法进行读取和修改了
只能通过get方法调用

package day07;

public class Test {
    
    
    public static void main(String[] args) {
    
    
        Shop s=new Shop();
        //加入一个顾客来买水果,先看了进价5.5元
        //System.out.println(s.buying);
        System.out.println(s.getBuying());

        //又看了看售价8元
        //System.out.println(s.price);
        System.out.println(s.getPrice());

        //他愤怒的把售价price改成为0.01
       // s.price=0.01; 已经无法修改
        //再调用sale方法
        s.sale(100,10);
    }
}

在这里插入图片描述


但是上面的代码还是不够完善,比如用户输入购买金额小于0怎么办,在比如用户金额小于应付金额怎么办?

接下来我们就继续修改,完善此代码:

package day07;

/**
 * 封装水果店属性和功能的类
 */
public class Shop {
    
    
       private double buying=5.5; //水果的进价5块5一斤
       private double price=8; //销量8块一斤
        double total; //销售量(斤数)

    /**
     *专门读取price属性的方法
     * 相当于老板可以告诉客人,这水果多少钱,但是客人不知道
     * @return
     */
    public double getBuying() {
    
    
        return buying;
    }

    public double getPrice() {
    
    
        return price;
    }

    /**
         * 卖水果的方法
         * money 多少钱
         * count 多少斤
         */
         void sale(double money,double count){
    
    
             /*公开的方法,要放出错*/
             if (money< 0 || count <=0){
    
      //数量<=0
                 System.out.println("购买的数量和钱必须>0");
             }else if (money<price*count){
    
     //钱给的不够
                 System.out.println("你的钱不够");
             }else{
    
    //正常执行逻辑
            //累加销量量
            total+=count;
            //输出本次购买的结果
            System.out.println("您购买的水果"+count
                    +"斤水果,收您"+money
                    +"元,找零"+(money-price*count));
               }
         }
}

根据修改,我们可以发现,现在代码逻辑执行正常了

package day07;

public class Test {
    
    
    public static void main(String[] args) {
    
    
        Shop s=new Shop();
        //加入一个顾客来买水果,先看了进价5.5元
        //System.out.println(s.buying);
        System.out.println(s.getBuying());

        //又看了看售价8元
        //System.out.println(s.price);
        System.out.println(s.getPrice());

        //他愤怒的把售价price改成为0.01
       // s.price=0.01; 已经无法修改
        //再调用sale方法
        s.sale(50,10); //付款50元,应付款80元,钱不够
        s.sale(-10,10);//付款-10元,购买的数量和钱必须>0
    }
}

在这里插入图片描述

protected和默认访问控制

●默认访问控制(不写任何修饰符)的成员,仅在同一个包中可用
●protected修饰的成员可以被同一个包中的类以及子类使用。

生活案例:包就好像我们现实中,我们家的小区,Shop类就好像我们小区内的一个水果店,默认只有本小区的人才知道,其他小区的人是不知道的。

public void sale(double money,double count){

如果我们想其他小区的人,也知道本小区有水果店呢? 现实中一般老板会在小区门口放一个大大的广告牌,public就正好相当于这个广告牌,路过的人,都能看见,都能调用。

在这里插入图片描述

如果我们想其他小区的人,也知道本小区有水果店呢? 现实中一般老板会在小区门口放一个大大的广告牌,public就正好相当于这个广告牌,路过的人,都能看见,都能调用。
package day07;

/**
 * 封装水果店属性和功能的类
 */
public class Shop {
    
    
       private double buying=5.5; //水果的进价5块5一斤
       private double price=8; //销量8块一斤
        double total; //销售量(斤数)

    /**
     *专门读取price属性的方法
     * 相当于老板可以告诉客人,这水果多少钱,但是客人不知道
     * @return
     */
    public double getBuying() {
    
    
        return buying;
    }

    public double getPrice() {
    
    
        return price;
    }

    /**
         * 卖水果的方法
         * money 多少钱
         * count 多少斤
         */
        public void sale(double money,double count){
    
    
             /*公开的方法,要放出错*/
             if (money< 0 || count <=0){
    
      //数量<=0
                 System.out.println("购买的数量和钱必须>0");
             }else if (money<price*count){
    
     //钱给的不够
                 System.out.println("你的钱不够");
             }else{
    
    //正常执行逻辑
            //累加销量量
            total+=count;
            //输出本次购买的结果
            System.out.println("您购买的水果"+count
                    +"斤水果,收您"+money
                    +"元,找零"+(money-price*count));
               }
         }
}

新建一个包,创建一个新的Test

package day08;

import day07.Shop;//导入day7中的Shop类

public class Test {
    
    
    public static void main(String[] args) {
    
    
        Shop s = new Shop();
        s.sale(100,10);
    }
}

我们可以发现,给方法加上public过后,隔壁小区的也能购买了
在这里插入图片描述


这时,我们在隔壁小区开一家分店,属性和方法,都和总店一样。
在这里插入图片描述

package day07;

/**
 * 封装水果店属性和功能的类
 */
public class Shop {
    
    
       private double buying=5.5; //水果的进价5块5一斤
       private double price=8; //销量8块一斤
        double total; //销售量(斤数)

    /**
     *专门读取price属性的方法
     * 相当于老板可以告诉客人,这水果多少钱,但是客人不知道
     * @return
     */
    public double getBuying() {
    
    
        return buying;
    }

    public double getPrice() {
    
    
        return price;
    }

    /**
         * 卖水果的方法
         * money 多少钱
         * count 多少斤
         */
       protected void sale(double money,double count){
    
    
             /*公开的方法,要放出错*/
             if (money< 0 || count <=0){
    
      //数量<=0
                 System.out.println("购买的数量和钱必须>0");
             }else if (money<price*count){
    
     //钱给的不够
                 System.out.println("你的钱不够");
             }else{
    
    //正常执行逻辑
            //累加销量量
            total+=count;
            //输出本次购买的结果
            System.out.println("您购买的水果"+count
                    +"斤水果,收您"+money
                    +"元,找零"+(money-price*count));
               }
         }
}

开一家分店

package day08;

import day07.Shop;

/**
 * 开了一个分店
 */
public class SubShop extends Shop {
    
    
    /**
     * 重写父类的sale方法,使用super调用父类的sale方法
     * JAVA中规定,子类重写父类的方法,子类中的方法访问控制范围不能小于父类方法的控制范围
     */
    protected void sale(double money,double count){
    
    
        super.sale(money,count);
    }
}

测试:

package day08;

public class Test {
    
    
    public static void main(String[] args) {
    
    
        SubShop ss= new SubShop();
        ss.sale(100,10);//100块,10斤
    }
}

在这里插入图片描述


访问控制符修饰成员

访问控制符修饰成员时的访问权限如下表所示:

在这里插入图片描述

●对于类的修饰可以使用public和默认方式。public修饰的类可以被任何一 个类使用;默认访问控制的类只可以被同一个包中的类使用。

猜你喜欢

转载自blog.csdn.net/QQ1043051018/article/details/112434809