目录

1. 封装

1.1 封装的概念

1.2 访问限定符

2. 包

2.1 包的概念

2.2 导入包中的类

2.3 自定义包

2.3.1 包的基本规则

2.3.2 创建一个包

2.4 包访问权限——defualt

3. 何为封装

3.1 private 关键字

4. static 成员

4.1 对学生类的进一步思考

4.2 static 修饰成员变量

4.3 static 修饰成员方法

4.4 private static 修饰的成员变量

4.5 对静态成员变量的初始化

4.5.1 普通代码块

4.5.2 构造块

4.5.3 静态块


1. 封装

1.1 封装的概念

面向对象程序三大特性:封装、继承、多态。而类和对象阶段,主要研究的就是封装特性。

对于计算机使用者而言,不用关心内部核心部件,比如主板上线路是如何布局的,CPU内部是如何设计的等,只需要知道,怎么开机、怎么通过键盘和鼠标与计算机进行交互即可。因此计算机厂商在出厂时,在外部套上壳子,将内部实现细节隐藏起来,仅仅对外提供开关机、鼠标以及键盘插孔等,让用户可以与计算机进行交互即可。这也算一种封装。

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

1.2 访问限定符

Java 中主要通过类和访问权限来实现封装:类可以将数据以及封装数据的方法结合在一起,更符合人类对事物的认知,而访问权限用来控制方法或者字段能否直接在类外使用。Java 中提供了四种访问限定符:

范围 private default protected public
1 同一包中同一类
2 同一包中不同类
3 不同包中的子类
4 不同包中的非子类

这里对 default 说明一下,defualt 表示默认的意思,并不是真的在成员变量前加一个default的单词,而是什么都不加,默认权限为同一包同一类以及同一包中不同类。而 public:可以理解为一个人的外貌特征,谁都可以看得到。private:只有自己知道,其他人都不知道。protected 主要是用在继承中,继承部分详细介绍。

为了更好地了解 private、default 及public 的区别,下面介绍的概念

2. 包

2.1 包的概念

在面向对象体系中,提出了一个软件包的概念,即:为了更好的管理类,把多个类收集在一起成为一组,称为软件包。有点类似于目录。比如:为了更好的管理电脑中的歌曲,一种好的方式就是将相同属性的歌曲放在相同文件下,也可以对某个文件夹下的音乐进行更详细的分类。

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

2.2 导入包中的类

Java 中已经提供了很多现成的类供我们使用,例如 Date 类:可以使用 java.util.Date 导入 java.util 这个包中的 Date 类。

    public static void main(String[] args) {java.util.Date date4 = new java.util.Date();//得到一个毫秒级的时间戳System.out.println(date4.getTime());}

这种写法略显麻烦,可以使用 import 语句导入包。

import java.util.Date;
public class Test {
public static void main(String[] args) {
Date date = new Date();
// 得到一个毫秒级别的时间戳
System.out.println(date.getTime());
}
}

如果需要使用 java.util 中的其他类, 可以使用 import java.util.*  。但不是把 util 包里面所有类都导入,而是需要用到谁就导入哪个类。

import java.util.*;
public class Test {
public static void main(String[] args) {
Date date = new Date();
// 得到一个毫秒级别的时间戳
System.out.println(date.getTime());
}
}

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

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

编译报错,所以最好使用完整的类名:

import java.util.*;
import java.sql.*;
public class Test {
public static void main(String[] args) {
java.util.Date date = new java.util.Date();
System.out.println(date.getTime());
}
}

可以使用 import static 导入包中静态的方法和字段,但不建议如此使用

在计算一个数的 n 次方的时候,使用了 Math.pow(x , 10),发现这里并没有写包,也能使用。

//导入了 Math 类的 所有的静态方法 当然 是用的时候 取的
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 result = sqrt(pow(x, 2) + pow(y, 2));
System.out.println(result);
}
}

2.3 自定义包

2.3.1 包的基本规则

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

2. 包名需要尽量指定成唯一的名字, 通常会用公司的域名的颠倒形式(例如 com.baidu.demo1 )

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

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

2.3.2 创建一个包

每次新建一个项目的时候,都会在 src 里创建类。那么 src 就是 IDEA 默认的一个自定义包。那我们该如何创建一个自己的包呢?

右击 src,NEW 处,点 Package。弹出 New Pacage 小方框, 在里面填入域名的颠倒形式,比如 com.baidu.www。

紧接着右击新建包,在 New 处 ,新建一个新的类即可。此时在 src 的文件下就可以看见三个文件了,分别是 com 、baidu 以及 www。

2.4 包访问权限——defualt

在 src 处再创建一个包,com.baidu.www2 。打开 baidu 文件发现有 www,以及 www2,这就是两个不同的包。

package com.baidu.www;class Size{int size1 = 99;
}public class Text {int size2 = 999;public void show(){System.out.println(size2);//同一个包 同一个类使用}public static void main(String[] args) {Size sz = new Size();System.out.println(sz.size1);//同一个包 不同类使用}
}
package com.baidu.www2;public class Text2 {public static void main(String[] args) {com.baidu.www.Text text = new com.baidu.www.Text();System.out.println(text.size2);}
}

在包 www2 中导入包 www1 中的 Text 类,想打印默认权限的 size2,编译报错。因为 size2 是default 的,不允许其他包访问。

2.5 常见的包

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 编程开发包。

除了第一个包,后面的包需要程序员手动 import。

3. 何为封装

3.1 private 关键字

对类的某些属性及方法用 private 来修饰,从而对外隐藏这些细节,达到封装的目的。而被 private修饰的变量及方法,权限的变小了,只能在类中使用。

class Person{private String name;private int age;private void eat(){System.out.println("吃饭!");}
}public class Text {public static void main(String[] args) {Person person1 = new Person();System.out.println(person1.name);}
}

上述代码中,name ,age 以及方法 studentId 都被private修饰,只能在 Person 类中访问,所以在Text 类中访问 name 的时候,编译会报错。

那么 private 关键字修饰的成员变量,该如何初始化?—— 使用构造方法

可以自己写,但也可以让 IDEA 自己生成:右击,选择 Generate -> Constructor ,按住 Ctrl 可选择自己想要的变量。

class Person{private String name;private int age;private void eat(){System.out.println("吃饭!");}public Person(String name, int age) {this.name = name;this.age = age;}public void show(){System.out.println(name+" "+age);}
}public class Text {public static void main(String[] args) {Person person1 = new Person("吹画",33);person1.show();}
}

那如果后续使用过程中,想要修改 name 和 age 的值,又该如何呢?

同样右击,选择 Generate -> Getter and Setter , 同样 Ctrl 选择想要的变量,就能生成多个 Getter 与 Setter 方法。

class Person{private String name;private int age;private void eat(){System.out.println("吃饭!");}public Person(String name, int age) {this.name = name;this.age = age;}public void show(){System.out.println(name+" "+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;}
}public class Text {public static void main(String[] args) {Person person1 = new Person("吹画",33);person1.show();person1.setName("翠花");person1.setAge(35);System.out.println(person1.getName());System.out.println(person1.getAge());person1.show();}
}

4. static 成员

4.1 对学生类的进一步思考

一个班的学生,姓名、年龄、学号等都是不一样的,可是班级呢?大家都是一个班的,如果按照以前的写法,每个学生对象会把类定义的所有成员变量都保存一份实例变量。那么如果一个班级有 45 人,那么 “X年X班” 这一信息会被重复保存45次,这么做,难道不是很浪费空间吗?所以这就有了static 关键字。

要表示学生的班级,这个属性并不需要每个学生对象中都存储一份,而是需要让所有的学生来共享。在 Java 中,被 static 修饰的成员,称之为静态成员,也可以称为类成员,其不属于某个具体的对象,是所有对象所共享的。

4.2 static 修饰成员变量

static 修饰的成员变量,称为静态成员变量,也叫类变量。特点有以下几条:

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

2. 既可以通过对象访问,也可以通过类名访问,但一般更推荐使用类名访问

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

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

class Student{private String name;private int age;private String gender;public static String highShool = "三年一班";//初始化public Student(String name, int age, String gender) {this.name = name;this.age = age;this.gender = gender;}//修改及类外访问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;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}
}
public class Text {public static void main(String[] args) {Student student1 = new Student("张帅",17,"男");Student student2 = new Student("莉丝",16,"女");Student student3 = new Student("荷包",19,"男");System.out.println(student1.highShool);System.out.println(student2.highShool);System.out.println(student3.highShool);System.out.println(Student.highShool);}
}

在 Text 中实例化了三个学生,通过对象的引用可以访问到班级,但是会有警告,而如果类名访问,则一切正常。由于 highShool 是类变量,前面说了,是不属于任何对象的,那么是不是在没有实例化对象之前,就可以访问呢?重写 main 方法如下:

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

输出

三年一班

甚至给一个极端的例子,来更好地看清成员变量的这个特性:

public class Text {public static void main(String[] args) {Student student = null;System.out.println(student.getName());//System.out.println(student.highShool);}
}

第一条打印,引发了空指针异常,而第二条打印,编译通过。

所以,静态的成员变量,可以借助类名直接访问,而不需要通过对象的引用来访问。

那么到这里总结一下,成员变量分为静态成员变量以及非静态成员变量。

4.3 static 修饰成员方法

Java 中,被 static 修饰的成员方法称为静态成员方法,不是某个对象所特有的。同成员变量一样,成员方法也分为两类,一是静态成员方法,亦叫类方法,一是非静态成员方法。

class Student{ ..................public static void doClass(){System.out.println("上课啦,同学们!");}
}
public class Text {public static void main(String[] args) {Student.doClass();}
}

同样的,静态成员方法不属于任何对象,因此在没有实例化对象之前,就可以通过类名来访问。

对于静态成员方法,有以下几点需要注意:

1. 同一个类中,静态成员方法可以互相直接调用

public class Text {public static void func(){System.out.println("烦死了!");}public static void func2(){func();//或者写成 Text.func();System.out.println("嗷嗷嗷!");}public static void main(String[] args) {func2();//Text.func2();}
}

2. 静态成员方法不可以直接调用非静态成员方法,一定得是通过对象的引用才能调用。

public class Text {public void func(){System.out.println("烦死了!");}public static void func2(){System.out.println("嗷嗷嗷!");}public static void main(String[] args) {Text funcc = new Text();funcc.func();func2();}
}

3. 在静态变量方法中,不能使用非静态的成员变量。

非静态的成员变量是属于对象的,要知道,前面代码中调用静态变量方法的时候,根本连对象都没有实例化,直接用类名调用。只要是非静态的数据成员,只能通过对象的引用调用。

class Student{ ..................public static void fun(){
//        System.out.println(this.name); //静态方法里不能使用this
//        System.out.println(name);//静态变量方法里得这样调用非静态成员变量Student student = new Student("666",88,"女");System.out.println(student.name);}
}public class Text {public static void main(String[] args) {Student.fun();}
}

4. 而非静态方法可以直接调用静态方法

    public void doClass(){System.out.println("上课啦,同学们!");fun();}public static void fun(){
//        System.out.println(this.name);
//        System.out.println(name);//静态变量方法里得这样调用非静态成员变量Student student = new Student("666",88,"女");System.out.println(student.name);}

4.4 private static 修饰的成员变量

同前面仅有 private 修饰的成员变量一样,修改或取得这个值,也用到了 Getter  和 Setter 方法。

这里再创建了一个城市类:

class CityInChina{private String province;private double longitude;private double latitude;private static String country = "中国";public CityInChina(String province, double longitude, double latitude) {this.province = province;this.longitude = longitude;this.latitude = latitude;}public String getProvince() {return province;}public void setProvince(String province) {this.province = province;}public double getLongitude() {return longitude;}public void setLongitude(double longitude) {this.longitude = longitude;}public double getLatitude() {return latitude;}public void setLatitude(double latitude) {this.latitude = latitude;}public static String getCountry() {return country;}public static void setCountry(String country) {CityInChina.country = country;}
}public class Text {public static void main(String[] args) {System.out.println( CityInChina.getCountry());}

输出

中国

在上面的代码中,我们发现,静态变量成员 country 访问权限为private ,其 Setter 及 Getter 方法 也是 static 修饰的,这样在调用的时候,可以用类名调用。

是不是又有同学有想法,说能不能就是不要 static ,那么后续要访问的时候,要得 new 一个对象,反而不方便了。

4.5 对静态成员变量的初始化

1. 就地初始化

private static String classRoom = "1102A";

2. 直接不写,编译器设置成默认值

private static String classRoom;

3. 使用Getter 和 Setter 来初始化

    public static String getCountry() {return country;}public static void setCountry(String country) {CityInChina.country = country;}

4. 通过代码块来进行赋值

在本小节中,重点讲解通过代码块来进行赋值。

代码块的分为:普通代码块、构造块(非静态代码块、实例代码块)、静态块以及同步代码块。

4.5.1 普通代码块

public class Text {public static void main(String[] args) {func2();}public static void func2(){System.out.println("aaaaaaaaaa");System.out.println("vvvvvvvvvvvvvv");System.out.println("嗷嗷嗷!");{//这块代码的执行 不需要条件int a = 10;System.out.println("定义在方法内部的代码块!普通代码块!");}}
}

4.5.2 构造块

在类里边,方法外边的代码块,又或者说在类里面,方法外面的变量,都是实例代码块或非静态代码块。初始化非静态的数据成员,会比构造函数更先执行

class CityInChina{ ..................{System.out.println("非静态代码块/实例代码块/构造代码块!->初始化非静态的数据成员");province = "GuangDong";longitude = 113.281;latitude = 23.1252;System.out.println(province);System.out.println(longitude);System.out.println(latitude);}
}public class Text {public static void main(String[] args) {CityInChina BeiJing = new CityInChina("BeiJing",116.20,39.56);System.out.println(BeiJing.getProvince());System.out.println(BeiJing.getLongitude());System.out.println(BeiJing.getLatitude());}
}

输出

非静态代码块/实例代码块/构造代码块!->初始化非静态的数据成员
         GuangDong
         113.281
         23.1252
         BeiJing
         116.2
         39.56

实际编译过程,是将构造代码块的内容拷贝到构造方法的前方,再依次执行。

4.5.1 和 4.5.2 在这里知识介绍语法,但在实际应用中,还是使用构造方法初始化非静态成员变量。

4.5.3 静态块

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

class CityInChina{............public CityInChina(){System.out.println("不带参数的构造方法!");}static {System.out.println("静态代码块-》初始化静态的数据成员/ 提前准备一些数据");}{System.out.println("非静态代码块/实例代码块/构造代码块!->初始化非静态的数据成员");}}public class Text {public static void main(String[] args) {CityInChina ShanXi = new CityInChina();}
}

输出

静态代码块-》初始化静态的数据成员/ 提前准备一些数据
       非静态代码块/实例代码块/构造代码块!->初始化非静态的数据成员
       不带参数的构造方法!

可以看到,执行顺序为 静态代码块 -> 构造块 -> 构造方法,不论静态代码块放在方法中的哪里,都会先执行。

class CityInChina{   ..................public static void fun(){System.out.println("啊啊啊啊!");}}public class Text {public static void main(String[] args) {CityInChina.fun();}
}

输出

静态代码块-》初始化静态的数据成员/ 提前准备一些数据
       啊啊啊啊!

由此可知,只要类被加载,静态代码块就会执行。而实例代码块得在创建对象之后,才会执行。

public class Text {public static void main(String[] args) {CityInChina.fun();CityInChina.fun();}
}

输出:

静态代码块-》初始化静态的数据成员/ 提前准备一些数据
       啊啊啊啊!
       啊啊啊啊!

可以看到,静态代码块只执行了一次。同样地,实例化多个对象,静态代码块也只会执行一次。

需要注意的是:

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

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

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

【JavaSE】类和对象 (二) —— 封装、包以及 static 关键字相关推荐

  1. 杨校老师课堂之Java类与对象、封装、构造方法

    杨校老师课堂之Java类与对象.封装.构造方法 本篇文章内容如下: 面向对象 类与对象 三大特征--封装 构造方法 教学目标 能够理解面向对象的思想 能够明确类与对象关系 能够掌握类的定义格式 能够掌 ...

  2. C++类与对象之封装篇

    C++类与对象之封装篇 一 . 封装的意义 封装的意义一 封装的意义二 二 . struct和class的区别(访问权限) 三 . 成员属性一般设置为私有(权限) 一 . 封装的意义 封装是C++面向 ...

  3. C++类和对象的封装

    C++类和对象的封装 C++面向对象的三大特性 例如 封装 封装的意义 示例1 示例代码 示例2 示例2代码 C++面向对象的三大特性 封装.继承.多态 C++认为万事万物都皆为对象,对象上有其属性和 ...

  4. Python快速入门(八)面向对象1:类、对象和封装

    Python快速入门(八)面向对象1:类.对象和封装 1.类和对象 1)类的定义 2)对象的定义 3)类和对象的关系 4)类的设计 2.第一个面向对象案列 代码1 代码2 3.设置对象属性 4.ini ...

  5. java 类与对象、封装、构造方法

    java 类与对象.封装.构造方法 面向对象 类与对象 三大特征--封装 构造方法 第1章 面向对象思想 1.1 面向对象思想概述 概述 Java语言是一种面向对象的程序设计语言,而面向对象思想是一种 ...

  6. 类、对象、封装、继承和多态等,一目了然!

    当谈到面向对象编程的概念和原则时,以下是一些示例来说明类.对象.封装.继承和多态的概念: 类(Class): 类是一种定义对象属性和行为的蓝图.它描述了对象的状态和行为.例如,我们可以创建一个名为&q ...

  7. javaSE各阶段练习题---面向对象-类与对象、封装、构造方法(1

    1-8题抽查提问,能够使用给自己的语言表述 1.什么是面向对象?1.是一种编程思想JAVA语言是一种面向对象的程序设计语言,而面向对象思想是一种程序设计思想.我们在面向对象思想的指引下, 使用java ...

  8. 第七章第二节:Java类和对象之封装、包和static成员

    专栏目录首页:[专栏必读]Java基础教程和数据结构内容导航和学习说明 文章目录 一:封装 (1)什么是封装 (2)访问限定符 二:包 (1)包的概念 (2)创建包 (3)导入包 (4)Java的im ...

  9. 三、kotlin的类和对象(二)

    theme: channing-cyan 继承★ kotlin 沿用了 java 的单继承系统, 不允许 c++ 的多继承出现, 但允许 kotlin 接口的多实现 open class Base(v ...

最新文章

  1. MySQL修改datadir目录
  2. python PIL 生成照片墙
  3. 数据库-表中导入数据-insert
  4. Spring REST:异常处理卷。 1个
  5. 今天早上买的这个猪蹄和花生辣条不是味道
  6. C语言学习笔记---结构体中的字符数组和字符指针
  7. 2020年CSDN最后一波上车机会,快来~~
  8. 嵌入式linux系统移植的四大步骤_嵌入式 Linux 产品技术评估之系统裁剪与启动速度...
  9. Arcgis自带世界矢量图
  10. 扩散模型 (Diffusion Model) 简要介绍与源码分析
  11. java 如何执行dig 命令_dig命令简介
  12. win64位MySQL5.7.32下载、安装及配置
  13. 住房贷款等额本息(等额本金)还款计划计算
  14. 用Matlab的FDAtool生成IIR滤波器参数
  15. 前端vue项目下载zip压缩包及附加
  16. ES8(Java API Client)查询详解
  17. 怎么html让元素脱离文档流,子元素设置绝对定位之后脱离文档流!
  18. 信安数学/网安数学——证明形如4k-1的素数有无限个
  19. 实例化枚举 java_java 枚举
  20. dmx计算机,DMX 文件扩展名: 它是什么以及如何打开它?

热门文章

  1. 用计算机娱乐教学思路,综合活动1 用计算机学习和娱乐
  2. Matplotlib 学习笔记
  3. python多分支语句实例_Python分支语句与循环语句应用实例分析
  4. 谁看了日本LINE的聊天记录
  5. 解决:“cxfreeze”无法运行,没有应用程序与此操作的指定文件有关联。
  6. 2022年元旦火车票开售时间公布,元旦火车票购票用便签提醒
  7. 为何会拿好人卡(二) 安全感是什么?
  8. ios内购功能是什么意思
  9. php程序root权限,获取root权限 php执行shell
  10. 最详细在Windows安装Xamarin.iOS教程