OOP之封装 (JAVA)

目录

概念

访问限定符

封装扩展之包 

包的概念

导入包中的类

自定义包

基本规则

操作步骤

static成员

概念

static修饰成员变量

static修饰成员方法

static成员变量初始化

Ⅰ.就地初始化

Ⅱ.静态代码块初始化

代码块概念及分类

普通代码块

构造代码块

静态代码块

同步代码块

总结


面向对象语言三大特性封装、继承、多态。本篇文章将讲述封装有关...何为封装?! 简而言之就是套壳屏蔽细节...


概念

封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。

注:接口有两层含义 -> ①.方法 ②.真正的接口(语法);此处加粗的接口为第一层含义

如下列代码,将成员变量name,age用private修饰后,外界不可直接获取、修改name和age,那么通过创建公开的方法getName()、setName()、getAge()...来对封装的成员变量进行操作

public class Person {
      private String name;
      private int age;
    
      public String getName(){
           return this.name;
      }

      public void setName(String name){
           this.name = name;
      }
}
Person person = new Person();
person.setName("张三");
System.out.println(person.getName());//打印张三

●快捷生成get()/set()方法 --> 鼠标右键Generate --> Getter(只要get()) 

                                                                                       Setter(只要set())   --> 可选中全部属性

                                                                                        Getter and Setter 

        --> ok --> 会自动生成get()/set()

因此,从语法上来说,封装就是被private修饰的成员变量或者成员方法,且只能在当前类当中使用。


访问限定符

JAVA中主要通过类和访问权限来实现封装:类可以将数据以及封装数据的方法结合在一起,而访问权限用来控制方法或者字段能否直接在类外使用

JAVA提供了四种访问限定符:

No范围privatedefaultprotectedpublic
1同一包中的同一类
2同一包中的不同类
3不同包中的子类
4不同包中的非子类

private: 私有的(只有自己知道,其他人都不知道)

default: 默认的,包访问权限 (!不要在成员/方法前加default,什么都不写即为默认)

protected: 受保护的 (主要用在继承中,继承部分详细介绍)

public: 公有的(哪都能用)

注:①.访问权限除了可以限定类中成员的可见性,也可以控制类的可见性

       ②.一般情况下,成员变量设置为private,成员方法设置为public


封装扩展之包 

包的概念

为了更好的组织和管理类,把多个类收集在一起成为一组,称为软件包。


导入包中的类

●使用import语句导入包

eg:专门组织管理和操作数组相关的类

import java.util.Arrays

包是对类、接口等的封装机制的体现,是一种对类或者接口等的很好的组织方式。包还有一个重要的作用:在同一个工程中允许存在相同名称的类,只要处在不同的包中即可。

例如,Date类既存在于java.util包中,也存在于java.sql包中

import java.util.Date;
import java.sql.Date;

如果需要使用java.util中的其他类,可以使用通配符*

import java.util.*

(只要是util底下的所有类,都能够进行适配)

但是,更建议显式的指定要导入的类名,否则还是容易出现冲突的情况。

import java.util.*;
import java.sql.*;
public class Test{
      public static void main(String[] args){
        //util和sql中都存在一个Date这样的类,此时就会出现歧义,编译出错
            Date date = new Date();
            System.out.println(date.getTime());
      }
}

//编译出错
//Error:(5,9)java:对Date的引用不准确
//java.sql中的类java.sql.Date和java.util中的类java.util.Date都匹配

在这种情况下需要使用完整的类名

java.util.Date date = new java.util.Date();

●使用import static导入包中静态的方法和字段

import static java.lang.Math.*; //导入导入这个类中的所有静态方法
public class Test{
     public static void main(String[] args){
          double x = 30;
          double y = 40;

          //静态导入的方式写起来更方便一些
          //double result = Math.sqrt( Math.pow(x,2) + Math.pow(y,2) );
          double redult = sqrt( pow(x,2) + pow(y,2) );
          System.out.println(result);
    }
}

*归根结底,包就是个文件夹,里面有很多类,类中有很多方法...


自定义包

基本规则

● 在文件的最上方加上一个package语句指定该代码在哪个包中.

●包名需要尽量指定成唯一的名字,通常会用公司的域名的颠倒形式(eg: com.baidu.www;)

●包名要和代码路径相匹配。eg:创建com.baidu.demo1的包,那么会存在一个对应的路径        com/baidu/demo1来存储代码

●如果一个类没有package语句,则该类被放到一个默认包中.

操作步骤

1.先创建一个包:右键src --> 新建 --> 包 

2.在弹出的对话框中输入包名(小写

3.在包中创建类:右键包名 --> 新建 --> 类,然后输入类名即可

4.此时可以看到磁盘上的目录结构已经被IDEA自动创建出来了

5.同时可以看到,在新创建的Test.java文件的最上方,就出现了一个package语句


static成员

概念

使用学生类实例化三个对象s1、s2、s3,每个对象都有自己特有的姓名、性别、年龄、学分绩点等成员信息,这些信息就是对不同学生进行描述的,如下所示:

public class Student{

      public static void main(String[] args){
           Student s1 = new Student("李雷","男",18,3.8);
           Student s2 = new Student("韩梅梅","女",19,4.0);
           Student s3 = new Student("Jim","男",18,2.6);
      }
}

假设三个同学是同一班的,那么他们上课肯定是在同一个教室,既然在同一个教室,能否在类中再加一个成员变量,来保存同学上课时的教室呢?!

答案是不行的 --> 在Student类中定义的成员变量每个对象都会包含一份(称为实例变量),因为需要使用这些信息来描述具体的学生。而现在要表示上课的教室,这个教室的属性并不需要每个学生对象中都存储一份,而是需要让所有的学生来共享

在JAVA中,被static修饰的成员,称之为静态成员,也可以称为类成员,其不属于某个具体的对象,是所有对象所共享的。


static修饰成员变量

static修饰的成员变量,称为静态成员变量

[静态成员变量特性]:

①.不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象的空间中(最大特性,即静态成员变量不属于对象)

②.既可以通过对象访问(会出现警告),也可以通过类名访问(推荐)

③.类变量存储在方法区当中

④.生命周期伴随类的一生(随类的加载而创建,随类的卸载而销毁)

public class Student{
      public static String classRoom = "101";
      
      public static void main(String[] args){
            //静态成员变量可以直接通过类名访问
            System.out.println(Student.classRoom);
      }
}

static修饰成员方法

一般类中的数据成员都设置为private,而成员方法设置为public,那设置之后,Student类中classroom属性如何在类外访问呢?!

public class Student{
      private static String classRoom = "101";
}

public class TestStudent{
     public static void main(String[] args){
          System.out.println(Student.classRoom);
     }
}

//Error:(10,35)java:classRoom在extend01.Student中是private控制

JAVA中,被static修饰的成员方法称为静态成员方法,是类的方法,不是某个对象所特有的。静态成员一般是通过静态方法来访问的。

public class Student{
      private static String classRoom = "101";

      public static String getClassRoom(){
           return classRoom;
      }
}
public class TestStudent{
     public static void main(String[] args){
          System.out.println(Student.getClassRoom());
     }
}

[静态方法特性]:

①.不属于某个具体的对象,是类方法

② .可以通过对象调用,也可以通过类名.静态方法名(...)方式调用(更推荐)

③.不能在静态方法中访问任何非静态成员变量

④ .静态方法中不能调用任何非静态方法,因为非静态方法有this参数,在静态方法中调用时候无法传递this引用

eg:

public static void func(){
     System.out.println("静态的!");
     System.out.println(this.name + "。。。");   //error
}

-->name的调用需要对象的引用来调用,而func()这个静态方法直接通过类名就能调用,不依赖于对象 --> 因此,在静态方法中,不能调用非静态的成员变量或者非静态的成员方法;静态方法当中不包含this


static成员变量初始化

静态成员变量的初始化分为两种:就地初始化、静态代码块初始化

Ⅰ.就地初始化

就地初始化指的是:在定义时直接给出初始值

public class Student{
      private String name;
      private String gender;
      //...
      private static String classRoom = "101";
}
Ⅱ.静态代码块初始化

什么是代码块?!!

代码块概念及分类

使用{}定义的一段代码称为代码块,可分为以下四种:普通代码块、*构造块、*静态块、同步代码块

普通代码块

定义在方法中的代码块(很少见)

public class Main{
      public static void main(String[] args){
           {//直接使用{}定义,普通方法块
            int x = 10;
            System.out.println("x1 = " +x);
           }
           int x = 100;
           System.out.println("x2 = " +x);
      }
}

//x1 = 10
//x2 = 100
构造代码块

构造块:定义在类中的代码块(不加修饰符),也叫:实例代码块

构造代码块

一般用于初始化实例成员变量

public class Student{
     //实例成员变量
     private String name;
     private String gender;
 
     {
       this.name = "小明";
       this.gender = "男";
     }
   
     public void show(){
          System.out.println("name:" + name + "gender:" + gender);
     }
}
public class Main{
     public static void main(String[] args){
          Student stu = new Student();
          stu.show();
     }
}
//name:小明gender:男

注:构造(实例)代码块只有在创建对象时才会执行 

静态代码块

使用static定义的代码块称为静态代码块。一般用于初始化静态成员变量

public class Student{
      private static String classRoom;

      static{
           classRoom = "101";
      }
}

注:

●静态代码块不管生成多少个对象,其只会执行一次

●静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的

●如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行(合并)

同步代码块

具体介绍在后续多线程部分...

总结

①.执行顺序:静态代码块 --> 构造代码块 --> 对应的构造方法 

 ②.静态代码块只执行一次

  • 20
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值