java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > OOP之封装Java

OOP之封装全过程(Java)

作者:鱼子酱Yuu_

文章讲解了封装作为面向对象三大特性之一,通过private修饰符和getter/setter方法实现数据隐藏,Java利用访问权限(private/default/protected/public)控制成员可见性,并介绍了包的组织管理作用及静态成员的初始化与执行顺序

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

概念

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

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

如下列代码,将成员变量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());//打印张三

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

访问限定符

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

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

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

注:

封装扩展之包

包的概念

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

导入包中的类

使用import语句导入包

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 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);
    }
}

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

自定义包

基本规则

操作步骤

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引用

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";
      }
}

注:

同步代码块

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

总结

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

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

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文