【Java】面向对象之封装
面向对象编程是对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界无法直接操作和修改。封装可以被认为是一个保护屏障,防止该类的代码和数据被其他类随意访问。要访问该类的数据,必须通过指定的方式。适当的封装可以让代码更容易理解与维护,也加强了代码的安全性。
封装原则:将属性隐藏起来,若需要访问某个属性,提供公共方法对其访问。
封装操作——使用private关键字
一、private的含义
- private是一个权限修饰符,代表最小权限。
- 可以修饰成员变量和成员方法。
- 被private修饰后的成员变量和成员方法,只在本类中才能访问。
二、private的使用
1.使用 private 修饰成员变量,代码如下:
public class Person {
private String name;
private int age;
}
2.提供 getXxx 方法 / setXxx 方法,可以访问成员变量,代码如下:
public class Person{
private String name;
private int age;
private boolean male;
public void setMale(boolean b) {
male = b;
}
//对于基本类型当中的boolean值,Getter方法一定要写成isXxx的形式,而setXxx规则不变。
public boolean isMale() {
return male;
}
public void setName(String str) {
name = str;
}
public String getName() {
return name;
}
public void setAge(int num) {
age = num;
}
public int getAge() {
return age;
}
}
对于Getter来说,不能有参数,返回值类型和成员变量对应;对于Setter来说,不能有返回值,参数类型和成员变量对应。
public class Person{
private String name;
private int age;
public void setName(String name) {
name = name;
}
public void setAge(int age) {
age = age;
}
}
仔细发现上面代码使用了成员变量和局部变量名称一致。经过测试你会发现成员变量赋值失败了。也就是说,在修改了 setXxx() 的形参变量名后,方法并没有给成员变量赋值!这是由于形参变量名与成员变量名重名,导致成员变量名被隐藏,方法中的变量名,无法访问到成员变量,从而赋值失败。所以,我们只能使用this关键字,来解决这个重名问题。
this的含义:this代表所在类的当前对象的引用(地址值),即对象自己的引用。方法被哪个对象调用,方法中的this就代表那个对象。即谁在调用,this就代表谁。
使用 this 修饰方法中的变量,解决成员变量被隐藏的问题,代码如下:
public 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;
}
}
方法中只有一个变量名时,默认也是使用 this 修饰,可以省略不写。
构造方法
一、定义构造方法
当一个对象被创建时候,构造方法用来初始化该对象,给对象的成员变量赋初始值。
无论你与否自定义构造方法,所有的类都有构造方法,因为Java自动提供了一个无参数构造方法,一旦自己定义了构造方法,Java自动提供的默认无参数构造方法就会失效。
定义格式:
修饰符 类名称(参数列表){
// 方法体
}
构造方法的写法上,方法名与它所在的类名相同。它没有返回值,所以不需要返回值类型,甚至不需要void。使用构造方法后,代码如下:
public class Person{
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
注意事项:
1. 如果你不提供构造方法,系统会给出无参数构造方法。
2. 如果你提供了构造方法,系统将不再提供无参数构造方法。
3. 构造方法是可以重载的,既可以定义参数,也可以不定义参数。
二、JavaBean
JavaBean 是 Java语言编写类的一种标准规范。符合 JavaBean 的类,要求类必须是具体的和公共的,并且具有无参数的构造方法,提供用来操作成员变量的 set 和 get 方法。
public class ClassName{
//成员变量
//构造方法
//无参构造方法【必须】
//有参构造方法【建议】
//成员方法
//getXxx()
//setXxx()
}
编写符合 JavaBean 规范的类,以Person类为例,标准代码如下:
public class Person{
private String name;
private int age;
// 无参构造方法
public Person() {
// 方法体
}
// 有参构造方法
public Person(String name, int age) {
this.name = name;
this.age = 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;
}
}
static关键字
关于 static 关键字的使用,它可以用来修饰的成员变量和成员方法,被修饰的成员是属于类的,而不是单单是属于某个对象的。也就是说,既然属于类,就可以不靠创建对象来调用了。
一、类变量
1.定义类变量
当 static 修饰成员变量时,该变量称为类变量(也称为静态变量)。该类的每个对象都共享同一个类变量的值。任何对象都可以更改该类变量的值,但也可以在不创建该类的对象的情况下对类变量进行操作。
类变量:使用 static关键字修饰的成员变量也称为静态变量。
定义格式:static 数据类型 变量名;
定义一个学生类,让学生学号自增?这样我们就需要一个变量,与单独的每一个学生对象无关,而是与整个班级同学数量有关。所以,我们可以定义一个静态变量实现数据共享。代码如下:
public class Student {
private int id; // 学号
private String name; // 姓名
private int age; // 年龄
static String room; // 所在教室
private static int idCounter = 0; // 学号计数器,每当new了一个新对象的时候,计数器++
public Student() {
this.id = ++idCounter;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
this.id = ++idCounter;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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;
}
}
2.使用类变量
类名.类变量名;
二、类方法
1.定义类方法
当 static 修饰成员方法时,该方法称为类方法 (也叫做静态方法)。静态方法在声明中有 static ,建议使用类名来调用,而不需要创建类的对象。调用方式非常简单。
类方法:使用 static关键字修饰的成员方法,习惯称为静态方法。
定义格式:修饰符 static 返回值类型 方法名 (参数列表){ }
如在Student类中顶一个showInfo的静态方法,代码如下:
public static void showNum() {
System.out.println("num:" + idCounter);
}
2.使用类方法
类名.静态方法名(参数);
静态方法调用的注意事项:
- 静态方法可以直接访问类变量和静态方法。
- 静态方法不能直接访问普通成员变量或成员方法。反之,成员方法可以直接访问类变量或静态方法。
- 静态方法中,不能使用this关键字。
被static修饰的成员(不管是类变量还是类方法)可以并且建议通过类名直接访问。虽然也可以通过对象名访问静态成员,原因即多个对象均属于一个类,共享使用同一个静态成员,但是不建议,会出现警告信息。
public class Xiaohei {
public static void main(String[] args) {
// 访问类变量
System.out.println(Student.idCounter);
// 调用静态方法
Student.showNum();
}
}
三、静态原理图解
static 修饰的内容:
- 是随着类的加载而加载的,且只加载一次。
- 存储于一块固定的内存区域(静态区),所以,可以直接被类名调用。
- 它优先于对象存在,所以,可以被所有对象共享。
因为在内存当中是【先】有的静态内容,【后】有的非静态内容,所以这也是为什么静态不能直接访问非静态。
四、静态代码块
静态代码块:定义在成员位置,使用static修饰的代码块{ }。
位置:类中方法外。
执行:随着类的加载而执行且执行一次,优先于main方法和构造方法的执行。
格式:
public class ClassName{
static {
// 执行语句
}
}
作用:给类变量进行初始化赋值。用法演示,代码如下:
public class Game {
public static int number;
public static ArrayList<String> list;
static {
// 给类变量赋值
number = 2;
list = new ArrayList<String>();
// 添加元素到集合中
list.add("张三");
list.add("李四");
}
}
五、总结
static 关键字,可以修饰变量、方法和代码块。在使用的过程中,其主要目的还是想在不创建对象的情况下去调用方法。