• 七千字带你了解封装等机制


    在这里插入图片描述

    一、封装

    面向对象程序三大特性:封装、继承、多态。封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。将自身的对象属性隐藏起来,对外只通过接口和对象进行访问.

    1.1如何封装?

    封装是将对象的属性进行访问权限的控制,使不能进行直接访问.

    class Person {
        private String name;
        private int age;
    }
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述
    我们可以发现进行封装之后,我们不能轻易的去赋值。这样还有一个好处是我们不用去管属性名是否改变,而且通过一定的方法去赋值即访问。

    对属性的访问权限设置为private,这样Person的属性只能在本类访问,信息的安全就有所保障了.
    在这里插入图片描述

    那如何访问这些封装的属性呢?

    class Person {
        private String name;
        private int age;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    代码如下(示例):

    public static void main(String[] args) {
            Person person = new Person();
            person.setName("张三");
            person.setAge(18);
            System.out.println("name: "+person.getName()+" age: "+person.getAge());
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    通常情况下,访问属性的这些方法被称为getter和setter方法。
    因此,任何要访问类中私有成员变量的类都要通过这些getter和setter方法。

    1.2封装的优点

    1. 良好的封装能够减少耦合。
    2. 类内部的结构可以自由修改。
    3. 可以对成员变量进行更精确的控制。
    4. 隐藏信息,实现细节。

    二、包的使用

    2.1包是什么?

    包是对类、接口等的封装机制的体现,是一种对类和接口等的很好的组织方式。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    我们发现包实际是我们盘符中的一个文件夹,每一个类是文件夹里的一个文件。
    那一个包中允许出现相同名称的类吗?
    在这里插入图片描述
    我们可以发现电脑无法在一个文件夹里命名两个相同的文件,所以一个包里不允许出现相同名称的类.

    2.2如何导入包中的类

    public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
          }
    
    • 1
    • 2
    • 3

    当我们想生成系统定义的对象或者访问方法时,因为系统限权的设置,我们直接访问就会出现下面的情况:
    在这里插入图片描述
    我们需要使用import语句引入包:

    import java.util.Scanner;
    public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
          }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这样即可,如果需要使用包中许多的类可以直接使用import java.util.*;

    import java.util.*;
    public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
          }
    
    • 1
    • 2
    • 3
    • 4

    这样就可以使用所有这个包中的类了,但不会直接导入包中的所有的类,而是自己使用那个类时,系统自动加载那个类.
    包中的类使用冲突:

    import java.util.*;
    import java.sql.*;
    public static void main(String[] args) {
            Date date = new Date();
            System.out.println(date.getTime());
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    因为sql和util中的类都有Date,系统不知道访问那个,就会发生上述错误.
    代码如下(示例):

    public static void main(String[] args) {
    java.util.Date date = new java.util.Date();
    }
    
    • 1
    • 2
    • 3

    在这里插入图片描述
    这种情况使用完整的类名.

    2.3常用包介绍

    1. java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入。
    2. java.lang.reflect:java 反射编程包;
    3. java.net:进行网络编程开发包。
    4. java.sql:进行数据库开发的支持包。
    5. java.util:是java提供的工具程序包。(集合类等) 非常重要
    6. java.io:I/O编程开发包。

    三、static的使用

    3.1static修饰变量

    static修饰的成员变量,称为静态成员变量,不属于具体的某个对象,而是所有对象共用一份.

    class Student {
        private String name;
        public static String classHome = "001";
    }
        public static void main(String[] args) {
            System.out.println(Student.classHome);
            Student student1 = new Student();
            System.out.println(student1.classHome);
            Student student2 = new Student();
            System.out.println(student2.classHome);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述

    我们可以通过以上对static变量的调用,可以发现以下几点:

    1. 不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象的空间中
    2. 既可以通过对象访问,也可以通过类名访问,但一般更推荐使用类名访问
    3. 类变量存储在方法区当中
    4. 生命周期伴随类的一生(即:随类的加载而创建,随类的卸载而销毁)

    3.2static修饰方法

    一个类中的普通的成员属性使用private封装起来,实现public方法供外部调用。那private修饰的static的成员变量,外部如何访问呢?

    class Student {
        private String name;
        private static String classHome = "001";
        public static String getClassHome() {
            return classHome;
        }
    }
    public static void main(String[] args) {
            System.out.println(Student.getClassHome());
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    static修饰的成员方法,是类的方法,静态成员变量需要用静态方法来访问.

    静态方法的特性:
    1.不属于具体的对象,是类的方法.
    2.可以使用对象调用,但不推荐.
    3.不能在静态方法中访问非静态成员变量.
    4.不能在静态方法调用非静态方法.

    四、代码块

    4.1普通代码块

    public static void main(String[] args) {
            {
                System.out.println("haha");
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述
    直接定义在方法中的代码块,即为普通代码块

    4.2静态代码块

    用于static修饰的代码块即为静态代码块,可初始化静态成员变量。

    class Student {
        public static String classHome;
        static {
            classHome = "001";
        }
    }
    public static void main(String[] args) {
            System.out.println(Student.classHome);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述
    我们可以发现我们为new对象,直接打印static成员变量时,static成员变量已经经过static代码块赋值.

    1.静态代码块在程序中只会执行一次(用于静态变量初始化)
    2.静态成员变量时类的属性,JVM在加载类时开辟空间并初始化
    3.一个类如果有多个静态代码块,编译时,按照顺序执行

    4.3实例代码块

    实例代码块又称构造代码块,顾名思义是用来初始化普通成员变量的

    class Student {
        public String name;
        public int age;
        {
            name = "张三";
            age = 18;
        }
    }
     public static void main(String[] args) {
            Student student = new Student();
            System.out.println("name: "+student.name+" age: "+student.age);
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    我们可以发现我们在创建对象时实例代码块执行对对象进行赋值,因为它是依赖每一个对象的,因此会多次执行。

    五、内部类

    5.1什么是内部类

    简单地说就是:定义在一个类内部的类

    class OutClass{//外部类
       class InnerClass{//内部类
       }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注意: 虽然内部类外部类在一个java文件,但编译后会形成两个不同的字节码文件.

    5.2静态内部类

    class OutClass {
        public int size;
        static int age;
        public void funcSize() {
            System.out.println(size);
        }
        public static void funcAge() {
            System.out.println(age);
        }
        static class InnerClass {
        //静态内部类只能访问外部的静态成员和方法.
            public void funInner() {
                age = 18;
                funcAge();
            }
        }
    
        public static void main(String[] args) {
            OutClass.InnerClass innerClass = new OutClass.InnerClass();
            innerClass.funInner();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这里插入图片描述

    1.在静态内部类只能访问外部类中的静态成员和方法
    2.创建内部类对象时,不需要先创建外部类对象

    在内部类如何访问外部类的成员和方法?

     static class InnerClass {
            public void funInner() {
                OutClass outClass = new OutClass();
                outClass.size = 20;
                outClass.funcSize();
                age = 18;
                funcAge();
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述
    我们可以通过外部类对象在内部类访问外部类成员变量和方法.

    5.3实例内部类

    class OutClass {
        public int size;
        static int age;
        public  void funcSize() {
            System.out.println("size: "+size);
        }
        public static void funcAge() {
            System.out.println("age: "+age);
        }
        class InnerClass {
            String name;
            public void funcInnerClass() {
                size = 20;
                age = 18;
                name = "张三";
                funcSize();
                funcSize();
                System.out.println("name: "+name);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在这里插入图片描述
    当内部类中的成员变量和外部类重名了,怎么访问?

    class InnerClass {
            int size;
            public void funcInnerClass() {
                OutClass.this.size = 20;
                age = 18;
                funcSize();
                funcAge();
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述
    可以通过外部类名.this.成员变量名访问.

    1. 外部类中的任何成员都可以在实例内部类方法中直接访问
    2. 实例内部类所处的位置与外部类成员位置相同,因此也受public、private等访问限定符的约束
    3. 在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名
      称.this.同名成员 来访问
    4. 实例内部类对象必须在先有外部类对象前提下才能创建
    5. 实例内部类的非静态方法中包含了一个指向外部类对象的引用
    6. 外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象。

    5.4局部内部类

    class OutClass {
        int size = 20;
        public void funcSize() {
            int age = 18;
            class InnerClass{
                public void funcInnerClass() {
                    System.out.println(size);
                    System.out.println(age);
                }
            }
            InnerClass innerClass = new InnerClass();
            innerClass.funcInnerClass();
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述
    局部内部类是定义在外部类方法体或者普通代码块中的内部类.

    1.局部内部类只能使用在所定义的方法体内部
    2.不能被public,static修饰
    3.编译器有自己的字节码文件,命名为:外部类$内部类.class

    在这里插入图片描述

  • 相关阅读:
    合成事件在san.js中的应用
    Outside ExpertPDF HtmlToPdf 转换器 17.0
    linux 创建git项目并提交到gitee(保姆式教程)
    java 并发执行批量异步任务(Future、 CompletableFuture 实现)
    Java8新特性Stream流详解
    IntelliJ IDEA运行JDK 19-ea问题
    spring
    JMeter笔记2 | JMeter原理及测试计划要素
    Docker 安装 Mongo
    天工杂志天工杂志社天工编辑部2022年第25期目录
  • 原文地址:https://blog.csdn.net/buhuisuanfa/article/details/126212235