• 面向对象(基础)特征一:封装性(encapsulation)



    面向对象特征之一:封装性

    一、介绍

    (1)封装性

    1. 为什么需要封装性?
    • 我要用洗衣机,只需要按一下开关和洗涤模式就可以了。有必要了解洗衣机内部的结构吗?有必要碰电动机吗?
    • 我要开车,我不需要懂离合、油门、制动等原理和维修也可以驾驶。

    随着我们系统越来越复杂,类会越来越多,那么类之间的访问边界必须把握好,面向对象的开发原则要 遵循“ 高内聚、低耦合 ”。 高内聚、低耦合是软件工程中的概念,也是UNIX 操作系统设计的经典原则。

    内聚,指一个模块内各个元素彼此结合的紧密程度;耦合指一个软件结构内不同模块之间互连程度的度量。内聚意味着重用和独立,耦合意味着多米诺效应牵一发动全身。

    内聚:把特定的内容封装到不同的类里面,把类里面特定的功能封装到不同的方法当中。

    耦合:相互之间要调用的时候,只对外暴露需要用的,不需要使用的细节就不对外暴露了。

    理论上:

    • 高内聚类的内部数据操作细节自己完成,不允许外部干涉;
    • 低耦合仅暴露少量的方法给外部使用,尽量方便外部调用。

    所谓封装,就是把客观事物封装成抽象概念的类,并且类可以把自己的数据和方法只向可信的类或者对 象开放,向没必要开放的类或者对象隐藏信息。

    通俗的说:把该隐藏的隐藏起来,该暴露的暴露出来。这就是封装性的设计思想。

    (2)权限修饰符

    1. 如何实现数据封装?
      2.1 权限修饰符
      Java规定了4种权限修饰,分别是:private缺省protectedpublic
      image.png
      image.png
      2.2 作用
      我们可以使用4种权限修饰来修饰类及类的内部成员。当这些成员被调用时,体现可见性的大小

    :只能使用public缺省修饰
    类的内部成员:可以使用4种权限修饰进行修饰。

    比如,这里的类用的是“缺省”:

    class Animal{   //动物
    
    }
    
    • 1
    • 2
    • 3

    这个类用的是“public”:

    public class AnimalTest {
        public static void main(String[] args) {
            Animal animal1=new Animal();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    但是使用“private”就不行,比如:
    image.png

    private修饰的是类的内部文件,此时AA就是一个类,它对自己可见,而且外边用不了,没有什么作用。

    protected也一样,修饰的属性让子类的类能够看到,主要指的是成员,类自己加没有什么意义。

    目前写的类是并列关系,都叫外部类,比如下面的AnimalTest类和Animal类:

    public class AnimalTest {
        public static void main(String[] args) {
            Animal animal1=new Animal();
        }
    }
    class Animal{   //动物
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    若在Animal类里面再写一个类,这个类就是内部类,内部类可以被四种权限修饰。(后边再说,不着急)

    2.3 开发中4种权限使用频率的情况:

    比较高:public、private

    比较低:缺省、protected

    1. 封装性的体现

    场景1:私有化(private)类的属性,提供公共(public)的get和set方法,对此属性进行获取或修改

    场景2:将类中不需要对外暴露的方法,设置为private.

    场景3:单例模式中构造器private的了,避免在类的外部创建实例。(放到static关键字后讲)

    二、案例

    (1)案例1

    看下面的代码:

    package yuyi.exer01.exe01;
    
    /**
     * ClassName: AnimalTest
     * Package: yuyi.exer01.exe01
     * Description:
     *
     * @Author 雨翼轻尘
     * @Create 2023/10/22 0022 13:29
     */
    public class AnimalTest {
        public static void main(String[] args) {
            Animal animal1=new Animal();
            animal1.name="金蟾";
            animal1.legs=4;
    
            System.out.println("name="+animal1.name+",legs="+animal1.legs);
            animal1.eat();
        }
    }
    class Animal{   //动物
        //属性
        String name;    //名字
        int legs;   //腿的个数
    
        //方法
        public void eat(){
            System.out.println("动物觅食");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    执行结果
    image.png

    ⚡注意

    不能直接在Animal类中写这种语句:System.out.println("动物");

    类里面只能有属性和方法,而上面的语句既不算属性,也不算方法,只是一个执行语句,它只能放在方法里面。

    class Animal{   //动物
        //属性
        String name;    //名字
        int legs;   //腿的个数
    
    	System.out.println("动物");	//不能这样写
        
        //方法
        public void eat(){
            System.out.println("动物觅食");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    现在想给legs设置一个判断逻辑,只有正偶数的值才能被输出。

    在Animal类中直接判断是不对的,如下:
    image.png

    但是属性可以在方法里面调用,所以我们可以在Animal类中写一个方法,在方法里面对legs进行逻辑判断。

    //设置legs属性值
    public void setLegs(int l){
            if(l>=0&&l%2==0){   //腿的个数为正偶数
                legs=l;
            }else{
                System.out.println("输入数据非法");
            }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在给属性赋值的时候,不需要再直接调用属性了,可以通过刚才的setLegs方法来调用,如下:

     //animal1.legs=4;
    animal1.setLegs(4); //若输入的值是正偶数,就能正确输出结果
    
    • 1
    • 2

    完整代码:

    public class AnimalTest {
        public static void main(String[] args) {
            Animal animal1=new Animal();
            animal1.name="金蟾";
            //animal1.legs=4;
            animal1.setLegs(4); //若输入的值是正偶数,就能正确输出结果
    
            System.out.println("name="+animal1.name+",legs="+animal1.legs);
            animal1.eat();
        }
    }
    class Animal{   //动物
        //属性
        String name;    //名字
        int legs;   //腿的个数
    
        /*不能直接在这里判断
        if(legs>=0){
    
        }*/
    
        //方法
        public void eat(){
            System.out.println("动物觅食");
        }
        public void setLegs(int l){
            if(l>=0&&l%2==0){   //腿的个数为正偶数
                legs=l;
            }else{
                System.out.println("输入数据非法");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    输出结果:
    image.png


    但是现在我们还是可以直接来调用属性,现在只不过是多了一种方式判断逻辑而已。

    那么如何让它彻底不能通过调用属性来给leg赋值?

    可以在定义属性的时候,在前面加一个权限修饰符private:(表示将这个属性私有化了,就是将它隐藏起来了,仅限在类的内部看到)

     private int legs;
    
    • 1

    此时外界(出了Animal类)就看不到legs属性了。

    所以直接调用legs属性就不被允许了。如下:
    image.png

    同时这里的legs也不能用了:
    image.png

    那怎么办呢?

    可以在Animal类中再写一个方法:

    //获取legs属性值
    public int getLegs(){
            return legs;
    }
    
    • 1
    • 2
    • 3
    • 4

    这个方法的权限是public,使用范围还是很大的。

    现在就可以调用了:

    System.out.println("name="+animal1.name+",legs="+animal1.getLegs());
    
    • 1

    此时编译器看到的就是这个方法的返回值类型(int类型的变量),所以就可以使用了。


    整体代码:

    package yuyi.exer01.exe01;
    
    /**
     * ClassName: AnimalTest
     * Package: yuyi.exer01.exe01
     * Description:
     *
     * @Author 雨翼轻尘
     * @Create 2023/10/22 0022 13:29
     */
    public class AnimalTest {
        public static void main(String[] args) {
            Animal animal1=new Animal();
            animal1.name="金蟾";
            
            //因为legs声明为private,是私有的,出了Animal类之外就不能调用了
            //animal1.legs=4;
    
            //只能通过setLegs(),间接对legs属性进行赋值
            animal1.setLegs(4); //若输入的值是正偶数,就能正确输出结果
    
            //System.out.println("name="+animal1.name+",legs="+animal1.legs);
            System.out.println("name="+animal1.name+",legs="+animal1.getLegs());
            
            animal1.eat();
        }
    }
    class Animal{   //动物
        //属性
        String name;    //名字
        private int legs;   //腿的个数
    
        /*不能直接在这里判断
        if(legs>=0){
    
        }*/
    
        //方法
        public void eat(){
            System.out.println("动物觅食");
        }
    
        //设置legs属性值
        public void setLegs(int l){
            if(l>=0&&l%2==0){   //腿的个数为正偶数
                legs=l;
            }else{
                System.out.println("输入数据非法");
            }
        }
    
        //获取legs属性值
        public int getLegs(){
            return legs;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    输出结果:
    image.png

    通过这个例子可以看到,为什么需要将一些必要的结构隐藏起来,因为不希望外边的用户可以随意的调用它,就需要将它私有化。如果外边想用,那就提供相应的方法,在方法里面对私有化的属性进行其他的设置。

    权限修饰符的使用,就是封装性的体现。


    👻总结

    在上述案例中,我们给Animal的对象的legs属性赋值。在实际的常识中,我们知道legs不能赋值为负数的。但是如果
    直接调用属性legs,是不能加入判断逻辑的。

    那怎么办呢?

    将legs属性私有化(private),禁止在Animal类的外部直接调用此属性。

    提供给legs属性赋值的setLegs()方法,在此方法中加入legs赋值的判断逻辑if(legs >= 0 && legs % 2 ==0)
    将此方法暴露出去,使得在Animal类的外部调用此方法,对legs属性赋值。

    提供给legs属性获取的getLegs()方法,此方法对外暴露。使得在Animal类的外部还可以调用此属性的值。

    若是在类的外部不想让用户获取legs的值,可以不写getLegs()方法,或者将它的权限修饰符设置为private,如下:

    private int getLegs(){
            return legs;
    }
    
    • 1
    • 2
    • 3

    此时getLegs方法对外也不暴露了,在Animal方法外面也就不能调用它了:
    image.png

    三、练习

    (1)练习1

    🌋题目描述

    创建程序,在其中定义两个类:Person和PersonTest类。定义如下:

    用setAge()设置人的合法年龄(0~130),用getAge()返回人的年龄。

    在PersonTest类中实例化Person类的对象b,调用setAge()和getAge()方法,体会Java的封装性。

    🤺代码

    package yuyi.exer01.exe01;
    
    /**
     * ClassName: Person
     * Package: yuyi.exer01.exe01
     * Description:
     *创建程序,在其中定义两个类:Person和PersonTest类。定义如下:
     * 用setAge()设置人的合法年龄(0~130),用getAge()返回人的年龄。
     * 在PersonTest类中实例化Person类的对象b,调用setAge()和getAge()方法,体会Java的封装性。
     *
     * @Author 雨翼轻尘
     * @Create 2023/10/22 0022 15:02
     */
    public class Person {
        //属性
        private int age;    //不对外暴露
    
        //设置age属性
        public void setAge(int agenumber){
            if(agenumber>=0&&agenumber<=130){
                age=agenumber;
            }else{
                System.out.println("输入的年龄有误");
            }
        }
    
        //获取age属性
        public int getAge(){
            return age;
        }
    }
    class PersonTest{
        public static void main(String[] args) {
            //创建Person实例1
            Person b=new Person();
    
            //b.age=21;   //编译不通过
            b.setAge(22);   //赋值
            System.out.println(b.getAge()); //获取值
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    ⚡输出结果
    image.png

    👻注意

    可以将这两个方法合并吗?如下:
    image.png

    现在两个功能合并在一起了,Age方法的耦合度更高,不建议这样来写!

    比如之前已经有了一个Person对象,现在我只想看看是多少岁,如果是左边的两种方法,我就可以通过getAge看一下是多少岁。

    但如果是右边的Age方法,此时我需要传进一个参数,然后又返回相同的数值,这就违背初衷了。

    每一个方法就只单纯的完成一个功能,在实际需要的时候再去组合这些方法完成特定的操作即可。不要刻意合并!!!

    (2)练习2

    🌋题目描述

    【自定义图书类】

    设定属性包括:

    书名bookName,

    作者author,

    价格price;

    方法包括:

    相应属性的get/set方法,

    图书信息介绍等。

    🤺代码

    【book.java】

    package yuyi.exer01.exe01;
    
    /**
     * ClassName: book
     * Package: yuyi.exer01.exe01
     * Description:
     * 【自定义图书类】
     * 设定属性包括:
     * 书名bookName,
     * 作者author,
     * 价格price;
     * 

    * 方法包括: * 相应属性的get/set方法, * 图书信息介绍等。 * * @Author 雨翼轻尘 * @Create 2023/10/22 0022 15:39 */ public class book { //属性 private String bookName; //书名 private String author; //作者 private double price; //价格 //方法 //1.1设置书名 public void setbookName(String b) { //... bookName = b; } //1.2获取书名 public String getbookName() { return bookName; } //2.1设置作者 public void setauthor(String a) { //... author = a; } //2.2获取作者 public String getauthor() { return author; } //3.1设置价格 public void setprice(double s) { //... price = s; } //3.2获取价格 public double getprice() { return price; } //4.获取图书信息 public String showInfo(){ return "bookName:"+bookName+",author:"+author+",price:"+price; } }

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    【bookTest.java】

    package yuyi.exer01.exe01;
    
    /**
     * ClassName: bookTest
     * Package: yuyi.exer01.exe01
     * Description:
     *
     * @Author 雨翼轻尘
     * @Create 2023/10/22 0022 15:54
     */
    public class bookTest {
        public static void main(String[] args) {
            book book1=new book();
            book1.setbookName("西游记");
            book1.setauthor("吴承恩");
            book1.setprice(30.46);
            System.out.println(book1.showInfo());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    可以使用Ctrl+Alt+L来调整代码格式(idea编译器)

    此时我们看到的就是对外暴露的方法。

    从后期来看,只要不是一些常量的话,一般都将属性私有化,对外都是暴露方法,通过方法对属性进行修改。

    ⚡输出结果
    image.png

    👻注意

    每创建一个对象,类里面的属性就会各自持有一份。

    现在“封装性”考虑的只是控制这些属性、方法在被访问的时候权限的大小而已。不会影响各个对象属性方法之间的关系,都会各自一份属性方法。

    (3)练习3

    🌋题目描述

    【普通员工类】

    (1)声明员工类Employee,

    • 包含属性:姓名、性别、年龄、电话,属性私有化
    • 提供get/set方法
    • 提供String getInfo()方法
      (2)在测试类的main中创建员工数组,并从键盘输入员工对象信息,最后遍历输出
      image.png

    image.png

    🤺代码

    【Employee.java】

    package yuyi.exer01.exe01;
    
    /**
     * ClassName: Employee
     * Package: yuyi.exer01.exe01
     * Description:
     *【普通员工类】
     * (1)声明员工类Employee,
     * - 包含属性:姓名、性别、年龄、电话,属性私有化
     * - 提供get/set方法
     * - 提供String getInfo()方法
     * (2)在测试类的main中创建员工数组,并从键盘输入员工对象信息,最后遍历输出
     *
     * @Author 雨翼轻尘
     * @Create 2023/10/22 0022 16:06
     */
    public class Employee {
        //属性
        private String name;
        private char sex;
        private int age;
        private String number;
    
        //方法
        //1.1设置姓名
        public void setname(String na){
            //...
            name=na;
        }
        //1.2获得姓名
        public String getname(){
            return name;
        }
    
        //2.1设置性别
        public void setsex(char se){
            //...
            sex=se;
        }
        //2.2获得性别
        public char getsex(){
            return sex;
        }
    
        //3.1设置年龄
        public void setage(int ag){
            //...
            age=ag;
        }
        //3.2获得年龄
        public int getage(){
            return age;
        }
    
        //4.1设置电话
        public void setnumber(String nu){
            //...
            number=nu;
        }
        //4.2获得电话
        public String getnumber(){
            return number;
        }
    
        //String getInfo()
        public String getInfo(){
            //return getname()+"\t"+getsex()+"\t"+getage()+"\t"+getnumber();
            return name+"\t"+sex+"\t"+age+"\t"+number;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70

    【EmployeeTest.java】

    package yuyi.exer01.exe01;
    
    import java.util.Scanner;
    
    /**
     * ClassName: EmployeeTest
     * Package: yuyi.exer01.exe01
     * Description:
     *
     * @Author 雨翼轻尘
     * @Create 2023/10/22 0022 18:03
     */
    public class EmployeeTest {
        public static void main(String[] args) {
            //Employee ie=new Employee();
    
            //创建Employee[] 假设只有两个员工
            Scanner scan=new Scanner(System.in);
    
            Employee[] ie=new Employee[2];
            for (int i = 0; i < ie.length; i++) {
                ie[i]=new Employee();
                System.out.println("--------添加第"+(i+1)+"个员工--------");
    
                System.out.print("姓名:");
                String name=scan.next();
    
                System.out.print("性别:");
                char sex=scan.next().charAt(0);
    
                System.out.print("年龄:");
                int age=scan.nextInt();
    
                System.out.print("电话:");
                String number=scan.next();
    
                //给指定的employee对象的各属性赋值
                ie[i].setname(name);
                ie[i].setsex(sex);
                ie[i].setage(age);
                ie[i].setnumber(number);
            }
    
            //遍历员工列表
            System.out.println("---------------员工列表----------------");
            System.out.println("编号\t姓名\t性别\t年龄\t电话");
            for (int i = 0; i < ie.length; i++) {
                System.out.println((i+1)+"\t"+ie[i].getInfo());
            }
            System.out.println("---------------员工列表完成----------------");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    运行输入:
    image.png

    ⚡输出结果
    image.png

    (4)练习4

    🌋题目描述

    测试权限修饰,先忽略protected。

    🤸测试

    在包test1里面创建一个类Order

    ackage yuyi.exer01.exe01.test1;
    
    public class Order {
        //声明不同权限的属性
        private int orderPrivate;
        int orderDefault;   //缺省权限
        public int orderPublic;
    
        //声明不同权限的方法
        private void methodPrivate(){
    
        }
        void methodDefault(){
    
        }
        public void methodPublic(){
    
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    ①在当前类里面

    在类的某一个方法内,上面的都可以调用。方法里面可以调属性,调方法。(如下面的test方法)

    package yuyi.exer01.exe01.test1;
    
    public class Order {
        //声明不同权限的属性
        private int orderPrivate;
        int orderDefault;   //缺省权限
        public int orderPublic;
    
        //声明不同权限的方法
        private void methodPrivate(){
    
        }
        void methodDefault(){
    
        }
        public void methodPublic(){
    
        }
    
        public void test(){
            //调用属性
            orderPrivate=1;
            orderDefault=2;
            orderPublic=3;
            
            //调用方法
            methodPrivate();
            methodDefault();
            methodPublic();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    权限再小,在当前类中也能用。

    当前包里面,当前类外面

    在当前test1包里面新建一个类OrderTest,调用Order类里面的结构。

    public class OrderTest {
        public static void main(String[] args) {
            //Order类的权限是public,在各个包里面都能看得见
            //因为是同一个包下,所以不用import
            Order order=new Order();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    即使现在的Order类是缺省修饰的,也可以被调用。因为缺省权限是本包内有效。如下:

    class Order{
        //...
    }
    
    • 1
    • 2
    • 3

    接下来测试调用属性和方法:

    package yuyi.exer01.exe01.test1;
    
    /**
     * ClassName: OrderTest
     * Package: yuyi.exer01.exe01.test1
     * Description:
     *
     * @Author 雨翼轻尘
     * @Create 2023/10/22 0022 19:45
     */
    public class OrderTest {
        public static void main(String[] args) {
            //Order类的权限是public,在各个包里面都能看得见
            Order order=new Order();
    
            //调用属性
            order.orderPublic=1;
            order.orderDefault=2;
            //order.orderPrivate=3; //不可以调用
    
            //调用方法
            order.methodDefault();
            order.methodPublic();
            //order.methodPrivate();    //不可以调用
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 调用属性

    image.png

    • 调用方法

    image.png

    private修饰符只能在本类里面调用,出了类就不行了。

    缺省可以在本包内调用,不会局限于类里面。(缺省就是default,但是现在不这么用了,因为容易和switch…case语句里面的default弄混)

    不同包里面

    在不同包下面创建文件,现在在test2包下创建OrderTest文件:
    image.png

    接下来想看一下test1包下的Order类里面的属性和方法在包test2内的OrderTest类中能不能调用。

    若此时Order类被缺省修饰,就不能在包test2内的OrderTest类中创建对象了,因为缺省修饰的只能在当前包内使用。

    class Order{
        //...
    }
    
    • 1
    • 2
    • 3

    可以看到,如果现在创建Order对象是不可以的:
    image.png

    所以,Order类的权限要大一点:

    public class Order{
        //...
    }
    
    • 1
    • 2
    • 3

    此时不会报错了,但是导包是必须的,如下:
    image.png


    看一下测试代码:

    package yuyi.exer01.exe01.test2;
    
    
    import yuyi.exer01.exe01.test1.Order;
    
    /**
     * ClassName: OrderTest
     * Package: yuyi.exer01.exe01.test2
     * Description:
     *
     * @Author 雨翼轻尘
     * @Create 2023/10/23 0023 0:04
     */
    public class OrderTest {
        public static void main(String[] args) {
            Order order=new Order();
    
            //调用属性
            order.orderPublic=1;
            //order.orderPrivate=2;	//不可以
            //order.orderDefault=3;	//不可以
    
            //调用方法
            order.methodPublic();
            //order.methodPrivate();	//不可以
           //order.methodDefault();	//不可以
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    只有Public修饰可以:
    image.png

    出了本包之后,不能调用Default和Private。

    总结:
    在这里插入图片描述
    代码敲的比较快,如果文章哪里有误,欢迎指正。

  • 相关阅读:
    【萌新解题】斐波那契数列
    如何才能让用例自动运行完之后,生成一张直观可看易懂的测试报告呢?
    【大厂AI课学习笔记NO.79】机器学习行业人才能力图谱
    【汇编语言04】第3章 寄存器(内存访问)——理论知识
    IDEA 高分辨率卡顿优化
    可以免费发外链的论坛有哪些?
    开机启动应用
    java数据结构与算法刷题-----LeetCode 面试题 16:10. 生存人数
    python3-常用数据结构
    基于Java开发小说自检测系统
  • 原文地址:https://blog.csdn.net/m0_55746113/article/details/133980641