Java 封装学习总结

本章学习目标

  • 重点掌握封装的作用

  • 掌握 private 关键字含义和基本用法

  • 掌握 this 关键字的含义和基本用法

  • 掌握 static 关键字的含义和基本用法

  • 掌握导入 jar 包


封装

什么是封装

一句话,封装就是对外部隐藏内部细节

封装的作用
  • 封装可以隐藏大量内部细节降低外部用户使用难度

  • 封装可以使修改内部细节不影响外部用户的使用

  • 封装可以降低内部组件之间的耦合度便于维护

private 和 public 关键字

Java 语言中提供了两个权限访问修饰符,分别是 private 和 public,它们专门实现 Java 对象的封闭和开放。

public 访问修饰符

public 表示公用的,也就是对外公开

public 访问修饰符可以修饰类、成员变量和方法,代码如下:

public class Man {
      public int age;
      public String name;
​
      public void play() {
          System.out.println("喜欢打游戏");
      }
}
​

以上代码在类、成员变量和方法中都使用了 public 权限访问修饰符,表示它们都对外开放,对象使用者可以访问它们,如下:

Man man = new Man();
man.age = 32;
man.name = "张三“;
man.play();
private 访问修饰符

private 表示私有的,也就是隐藏,不对外公开

假如我们不想随便对外公开年龄、姓名和兴趣,那么就可以使用 private 将其隐藏起来,让对象使用者没有权限访问,如下:

public class Man {
      private int age;
      private String name;
​
      private void play() {
          System.out.println("喜欢打游戏");
      }
}

还是用外部对象访问,如下:

Man man = new Man();
man.age = 32;
man.name = "张三“;
man.play();

看一看结果如何

C:\Users\xubin\Desktop\Java\MyProject\src\HelloWorld.java
Error:(9, 12) java: age Man 中是 private 访问控制
Error:(10, 12) java: name Man 中是 private 访问控制
Error:(11, 12) java: play() Man 中是 private 访问控制

编译报错了,错误提示是 private 访问权限,外部对象禁止访问。

Getter 访问器与 Setter 修改器

Getter 访问器和 Setter 修改器是为 private 修饰的类成员变量提供安全访问的一种方式

public class Man {
     private int age;
     private String name;
​
     public int getAge( ) {      // Getter 访问器  
           return age;
      }
    public void setAge(int age) {// Setter 修改器  
            this.age = age;
      }
}

使用 Getter 访问器与 Setter 修改器,如下:

Man man = new Man();
man.setAge(32);
System.out.println( man.getAge( ) );
Getter 访问器和 Setter 修改器的作用
  • 可以为 private 修饰的属性(或成员变量)提供统 一的外界访问通道

  • 可以为外界提供访问安全性(访问条件判断)

  • 可以在访问器中设置访问权限控制或管理(实现按权限级别访问内部数据)

总结

在面向对象编程中,我们需要考虑哪些成员变量或方法需要对外公开,提供给对象使用者(也就是 public);哪些成员变量或方法需要隐藏细节,禁止对象使用者访问。

this 关键字

在 Java 中,this 关键字指的是当前对象的引用,它有 5 种用法

1、消除语法歧义(最常用)

这种情况一般出现在有参构造器中,当构造器的参数与类的属性(或成员变量)名称完全相同时,导致 Java 编译器无法区别,从而产生语法歧义,编译报错。

解决办法就是使用 this 关键字,如下代码:

public class Man {
    private int age;
    private String name;
​
    public Man (int age, String name) {
        this.age = age;
        this.name = name;
    }
}

Man 类有两个成员变量,分别是 age 和 name,在使用有参构造器的时候,如果参数名和成员变量的名字相同,就需要使用 this 关键字消除歧义。

其中 this.age 是指类的成员变量,age 是指有参构造器的参数。

2、引用类的其他构造器

当一个类的构造器有多个,可以使用 this 关键字在一个构造器内部调用其他构造器,从而减少代码量

比如说,在无参构造器中调用有参构造器,如下代码:

public class Man {
    private int age;
    private String name;

    public Man(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public Man() {
        this(23, "张三"); //显示默认构造器调用有参构造器
    }
}

也可以在有参构造器中调用无参构造器,如下代码:

public class Man {
    private int age;
    private String name;

    public Man(int age, String name) {
        this(); // 有参构造器内部调用显式默认构造器
        this.age = age;
        this.name = name;
    }

    public Man() {
    }
}

需要注意的是,Java 语法要求 this() 必须是构造器方法体中的第一条语句,否则就会报错。不信,你可以自己试一试哈。

3、作为方法参数传递

先看下面的代码

public class Test {
    public Test() {
        print(this);
    }

    private void print(Test test) {
        System.out.println("print 方法:" + test);
    }

    public static void main(String[] args) {
        Test test = new Test();
        System.out.println("main方法:“+test);
    }
}

我在显式默认构造器中调用了 print( ) 方法,然后把 this 关键字作为参数传递给该方法,接着在 print( ) 方法中打印 this 关键字的值。在 程序入口 main() 方法中,实例化 Test 对象,然后同样打印对象名的值。

来打印看一下结果:

print方法: com.cmower.baeldung.this1.ThisTest@573fd745
main方法:com.cmower.baeldung.this1.ThisTest@573fd745

从结果中可以看得出来,this 关键字和 test 对象名都指向同一个对象的引用(或地址),而那个对象就是使用 new 关键字创建的 test 对象。

4、链式调用

学过 JavaScript,或者 jQuery 的读者可能对链式调用比较熟悉,类似于 a.b().c().d(),仿佛能无穷无尽调用下去。

在 Java 中,也可以使用 this 关键字编写链式调用,代码如下:

public class Man {
    private int age;
    private String name;

    public Writer() {
      
    }

    public Man SetName(String name) {
         this.name = name;
         return this;
     }

     public Man SetAge(String age) {
         this.age = age;
         return this;
     }
}

这时候,创建 Man 对象就可以通过链式调用的方式设置姓名和年龄

Man man  = new Man();
man.setName("张三“).setAge(23);
5、在内部类中访问外部类对象

自从 Java 8 的函数式编程出现后,就很少用到 this 在内部类中访问外部类对象了

public class Test {
    private String name;

    class InnerClass {
        public InnerClass() {
            Test test = Test.this;
            String name = test.name;
        }
    }
}

在内部类 InnerClass 的构造方法中,通过外部类.this 可以获取到外部类对象,然后就可以使用外部类的成员变量了,比如说 name。

总结

以上 5 种 this 关键字的使用没必要全部掌握,很多用法实际项目开发中很少或根本用不到,所以仅作了解而已即可。毕竟我们学 Java 是为了开发,应该关注使用最频繁的用法,如果花费太多精力去研究语言本身的各种稀奇古怪的用法,简直是本末倒置。

static 关键字

static 关键字可用于变量、方法、代码块,表示某个特定的成员只属于某个类本身,而不是该类的某个对象。

1、静态变量

静态变量也叫类变量,它属于一个类,而不是这个类的对象。

public class Man {
    private String name;
    private int age;
    public static int num;

    public Man(String name, int age) {
        this.name = name;
        this.age = age;
        num++;
    }
}

其中,num 被称为静态变量,它有别于 name 和 age 这两个成员变量,因为它前面多了一个修饰符 static。

这意味着无论这个类被实例化对象多少次,静态变量的值都会在所有实例化对象中共享。

Man man = new Man("张三", 32);
Man man2 = new Man("李四",35);

System.out.println(Man.num);

打印结果 num 的值为2,而不是 1。

静态变量和成员变量有着很大的不同,成员变量的值属于某个对象,不同的对象之间,值是不共享的;但静态变量不是的,它可以用来统计对象的数量,因为它是共享的。就像上面例子中的 num,创建一个对象的时候,它的值为 1,创建两个对象的时候,它的值就为 2。

  • 由于静态变量属于一个类,所以不能通过对象引用来访问,而应该直接通过类名来访问;

  • 不需要初始化类就可以访问静态变量

2、静态方法

静态方法也叫类方法,它和静态变量类似,属于一个类,而不是这个类的对象

public static void setNum(int num) {
    Man.num = num;
}

setNum() 就是一个静态方法,它由 static 关键字修饰

回忆一下,我们在这之间其实已经用了很多次静态方法,只是那时候不清楚而已。

总结
  • 抽象方法不能是静态方法

  • 静态方法不能使用 this 和 super 关键字

  • 静态方法可以访问所有其他静态方法和静态变量

  • 静态方法无法访问普通方法和成员变量

3、静态代码块

静态代码块可以用来初始化静态变量,尽管静态方法也可以在声明的时候直接初始化,但有些时候,我们需要多行代码来完成初始化。

public class man {
    public static int age;
    public static String name;

   // 静态初始化块
    static {
        age = 32;
        name = "张三“;
    }
}
静态类成员的注意事项:
  • 类的静态方法中不能调用非静态方法和非静态成员变量(也不能使用this和super)

  • 类的非静态方法中可以调用静态方法和静态成员变量

Jar 包

jar 包 ( Java Archive,Java 归档文件) 是与平台无关的压缩文件格式,它允许将多个 class 文件组合成一个压缩文件(文件后缀名 *.jar)

Jar 包的作用
  • 用于发布和使用第三方类库

  • 作为应用程序和扩展的构建单元

  • 作为组件、applet 或者插件程序的部署单位

  • 用于打包和组件相关的辅助资源

Jar 包的生成
  • DOS 命令

    jar 命令:用于将 class 文件打包成 jar 包
  • IDEA 生成和导入 Jar 包

posted @ 2021-08-24 19:32  嘛了对就念来过倒  阅读(81)  评论(0编辑  收藏  举报