目录
面向对象之封装
概述
指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
好处
隐藏实现细节,提供公共的访问方式
提高了代码的复用性
提高安全性
原则
将不需要对外提供的内容都隐藏起来。
把属性隐藏,提供公共方法对其访问。
private 关键字
定义与作用
- 是一个权限修饰符。
- 可以修饰成员(成员变量和成员方法)
- 被private修饰的成员只在本类中才能访问
最常见应用
把成员变量用private修饰
提供对应的getXxx()/setXxx()方法
例子:
class Student{
private String name;
private int age;
//无参构造方法
public Student(){
}
//带参构造方法
public Student(String name,int age){
this.name = name;
this.age = age;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return this.age;
}
}
class StudentTest{
public static void main(String[] args){
Student s = new Student();
//s.age = 18;//错误
s.setAge(18);
//s.name = "Alice";//错误
s.setName("Alice");
System.out.println(s.getName()+"---"+s.setName());
}
}
this 关键字
定义
代表所在类的对象引用,可看成当前类的一个对象
作用
解决局部变量隐藏成员变量的问题
参见上述例子。
构造方法
作用
给对象的数据进行初始化
格式
- 方法名与类名相同
- 没有返回值类型,连void都没有
- 没有具体的返回值
参见上述例子。
注意事项
- 如果不提供构造方法,系统会给出默认无参构造方法
- 如果提供了构造方法,系统将不再提供
- 构造方法也是可以重载的
小结
- 一般类的结构
- 成员变量
- 构造方法
- 无参构造方法
- 带参构造方法
- 成员方法
- getXxx( )方法
- setXxx( )方法
- 给成员变量赋值的方式
- 无参构造方法+setXxx( )
- 带参构造方法
类的初始化过程
- 以
Student s = new Student();
为例- 加载Student.class文件进内存(方法区)
- 在栈内存为s开辟空间
- 在堆内存为学生对象开辟空间
- 对学生对象的成员变量进行默认初始化
- 对学生对象的成员变量进行显式初始化
- 通过构造方法对学生对象的成员变量赋值
- 学生对象初始化完毕,把对象地址赋值给s变量
static 关键字
作用
使类中的成员变量或成员方法在该类创建的对象共享
特点
- 随着类的加载而加载
- 优先于对象存在
- 被类的所有对象共享
这是我们判断是否使用静态关键字的条件
如果某个成员变量是被所有对象共享的,那么就应该定义为静态的。
- 可以通过类名调用(推荐使用)
静态修饰的内容一般称其为:与类相关的类成员
注意事项
- 在静态方法中是没有this关键字的
理解:静态是随着类的加载而加载,this是随着对象的创建而存在。静态比对象先存在。先存在的东西访问不了后来产生的 - 静态方法只能访问静态的成员变量和静态的成员方法
访问 | 静态方法 | 非静态方法 |
---|---|---|
静态成员变量 | √ | √ |
静态成员方法 | √ | √ |
非静态成员变量 | × | √ |
非静态成员方法 | × | √ |
内存图
静态变量和成员变量的区别
- 所属不同
- 静态变量属于类,所以也称为为类变量
- 成员变量属于对象,所以也称为实例变量(对象变量)
- 内存中位置不同
- 静态变量存储于方法区的静态区
- 成员变量存储于堆内存
- 生命周期不同
- 静态变量随着类的加载而加载,随着类的消失而消失
- 成员变量随着对象的创建而存在,随着对象的消失而消失
- 调用不同
- 静态变量可以通过类名调用,也可以通过对象调用
- 成员变量只能通过对象名调用
使用场景
工具类中常用静态方法。如:Math类
例子:数组工具类 ArrayTool
public class ArrayTool {
//构造方法私有化,外界就不能创建ArrayTool对象
private ArrayTool(){ }
//遍历数组
public static void printArray(int[] arr){
for(int x = 0; x < arr.length; x++){
if(x == arr.length - 1){
System.out.println(arr[x]);
}else {
System.out.print(arr[x]+",");
}
}
}
//获取数组的最大值
public static int getMax(int[] arr) {
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
//获取数组中某个数的索引值
public static int getIndex(int[] arr,int value) {
int index = -1;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == value) {
index = i;
break;
}
}
return index;
}
}
class ArrayDemo{
public static void main(String[] args) {
int[] arr = {22,55,77,33,11,88};
//遍历
ArrayTool.printArray(arr);
//获取最大值
int max = ArrayTool.getMax(arr);
System.out.println("max:"+max);
//获取55的索引值
int index = ArrayTool.getIndex(arr, 55);
System.out.println("index:"+index);
}
}
制作说明书
- 过程:
写工具类 ->> 对这个类加入文档注释 ->> 用工具解析文档注释 - 注意事项:
- 工具类要使用public权限
- 加注释的格式如下述例子
- 解析的方式:
- 命令行:javadoc -d 目录 -author -version 工具类
- Eclipse:选中项目->右键选择 Export ->选择Java中的Javadoc -> 配置好点Finish即可
- 生成的说明书看 index.html 文件即可
- 例子:ArrayTool
/**
* 这是针对数组进行操作的工具类
* @author MJF
* @version V1.0
*
*/
public class ArrayTool {
/**
* 这是私有构造
*/
private ArrayTool(){}
/**
* 这是遍历数组的方法,遍历后的格式是:[元素1,元素2,...元素n]
* @param arr 要被遍历的数组
*/
public static void printArray(int[] arr){
System.out.print("[");
for(int x = 0; x < arr.length; x++){
if(x == arr.length - 1){
System.out.println(arr[x]+"]");
}else {
System.out.print(arr[x]+",");
}
}
}
/**
* 这是获取数组中最大值的方法
* @param arr 要获取最大值的数组
* @return 返回数组中的最大值
*/
public static int getMax(int[] arr) {
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
/**
* 获取指定元素在数组中第一次出现的索引,如果元素不存在,就返回-1
* @param arr 被查找的数组
* @param value 要查找的元素
* @return 返回元素在数组中的索引值,如果不存在,则返回-1
*/
public static int getIndex(int[] arr,int value) {
int index = -1;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == value) {
index = i;
break;
}
}
return index;
}
}
代码块
定义
在Java中,使用{ }括起来的代码被称为代码块
分类
根据其位置和声明的不同,可分为
- 局部代码块
局部位置,用于限定变量的声明周期,及早释放,提高内存利用率
- 构造代码块
在类中的成员位置,用{ }括起来的代码,每次调用构造方法执行前,都会先执行构造代码块
作用:可以把多个构造方法中的共同代码放到一起,对对象进行初始化
- 静态代码块
在类中的成员位置,用{ }括起来的代码,并且用static修饰
作用:一般是对类进行初始化
注意事项
- 静态代码块,构造代码块,构造方法执行顺序
静态代码块 -> 构造代码块 ->构造方法
- 静态代码块:无论调用该类多少次,只执行一次
- 构造代码块:每次调用构造方法都会执行
例子1:
public class Code {
//静态代码块
static {
int a = 1000;
System.out.println(a);
}
//构造代码块
{
int x = 100;
System.out.println(x);
}
//构造方法
public Code() {
System.out.println("Code");
}
//构造方法
public Code(int a) {
System.out.println("Code");
}
//构造代码块
{
int y = 200;
System.out.println(y);
}
}
class CodeDemo{
public static void main(String[] args) {
//局部代码块
{
int x = 10;
System.out.println(x);
}
//找不到符号
//System.out.println(x);
System.out.println("-----------------");
Code code = new Code();
System.out.println("-----------------");
Code code2 = new Code();
System.out.println("-----------------");
Code code3 = new Code(1);
System.out.println("-----------------");
}
}
运行结果如下:
例子2:(判断下列执行顺序)
public class Student {
static {
System.out.println("Student 静态代码块");
}
{
System.out.println("Student 构造代码块");
}
public Student() {
System.out.println("Student 构造方法");
}
}
class StudentDemo{
static {
System.out.println("StudentDemo 静态代码块");
}
public static void main(String[] args) {
System.out.println("main 方法");
Student s1 = new Student();
Student s2 = new Student();
}
}
运行结果如下: