Java基础 | Java封装 | 03
封装的概念和特点
封装
- 隐藏对象的信息
- 留出访问接口
其实生活中的许多操作都是封装好的,比如ATM机,我只要按照接口操作即可,不必关心内部的具体实现。
封装的代码实现
Java中的如何实现封装呢?主要通过以下三个步骤。
getter和setter可以通过IDE快速进行生成。
建议在使用构造函数给属性赋值的时候,也使用setter,这样就可以有对赋值的判断语句。
package com.imooc.animal;
/**
* 宠物猫类
*
* @author rowrycho
*
*/
public class Cat {
// 属性:昵称、年龄、体重、品种
private String name;
private int month;
private double weight;
private String species;
// 构造方法
public Cat() {
System.out.println("这是无参构造方法");
}
public Cat(String name) {
this(); // 调用无参构造方法
System.out.println("这是有参构造方法");
}
// 构造方法中也使用setter来进行赋值操作
public Cat(String name, int month, double weight, String species) {
this("你好");
this.setName(name);
this.setMonth(month);
this.setWeight(weight);
this.setSpecies(species);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
if(month<=0)
System.out.println("输入信息错误,宠物猫年龄必须大于0");
this.month = month;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
public String getSpecies() {
return species;
}
public void setSpecies(String species) {
this.species = species;
}
}
使用包进行类管理
Java中包的作用就是类似操作系统中文件夹的作用,包就是用来管理类文件的。
包的作用:
- 管理Java文件
- 解决同名文件冲突
注意:package语句必须放在程序的第一行。
因为单一职责原则,所以建议每个包内存储信息功能单一。
如何在A包中引入B包中的类?
import com.imooc.animal.*; // * 表示导入animal中全部类
import com.imooc.animal.Cat; // 只导入annimal中的Cat类
建议采用import 包名。类名;
的方式加载,提高效率。
同时注意,import com.imooc.*
并不能加载全部的类!因为import 包名.*
只能访问指定包名下的类,无法访问子包下的类。
如果导入的两个不同包出现了同名类,那么应该如何解决呢?
二者都使用全部路径,或者其中一方使用全路径即可。
public class Test {
public static void main(String[] args) {
// 使用全部路径导入,避免c
com.imooc.animal.Cat one = new com.imooc.animal.Cat();
com.imooc.mechanics.Cat two = new com.imooc.mechanics.Cat();
}
}
static关键字
public class Cat{
// static:静态 静态成员、类成员
public static int price;
public static void main(String[] args){
Cat one = new Cat();
one.price=150; // price=150
Cat two = new Cat();
two.price=300; // price=300
System.out.println(one.price); // price为300!
}
}
对象成员就是创建对象的时候才有,对象销毁时就会被删除。
但是static修饰的类成员,从类创建开始就存在,直到类被销毁才消失,而且每一个对象都是使用同一个类变量,也就是说不同对象操作是同一个类成员!
- 类对象共享
- 类加载时产生,销毁时释放,生命周期长
静态成员的访问方式
推荐通过 类.成员 的方式进行调用
one.price=200; // 对象.成员
Cat.price=200; // 类.成员
one.eat();
Cat.eat();
static的使用范围
- static + 成员属性
- static + 成员方法
静态成员不能调用非静态成员,非静态成员可以调用静态成员,使用this也是不小的(从加载顺序来进行理解)
代码块
代码块
- 普通代码块: 顺序执行,先出现,先执行
- 构造代码块:创建对象时调用,优先于构造方法执行
- 静态代码块:类加载时调用,优先于构造代码块执行
package com.imooc.animal;
/**
* 宠物猫类
*
* @author rowrycho
*
*/
public class Cat {
...
static {
System.out.println("这是静态代码块1");
}
static {
System.out.println("这是静态代码块2");
}
{
System.out.println("这是构造代码块1");
}
{
System.out.println("这是构造代码块2");
}
...
public void eat() {
{
System.out.println("这是普通代码块");
}
System.out.println("小猫吃鱼");
}
}
package com.imooc.animal;
public class CatTest {
public static void main(String[] args) {
// 实例化对象
Cat one = new Cat("花花", 2, 1000, "英国短毛猫");
Cat two = new Cat();
}
}
可以看到上图执行结果,静态代码块只会加载一次,而构造代码块每次新创建一个对象的时候会有加载。
- 无论产生多少类实例,静态代码块只会执行一次
- 仅希望执行一次的代码可以放在静态代码块中
执行顺序:静态代码块>构造代码块>构造方法
小结
封装
封装
* 隐藏对象的信息
* 留出访问接口
其实生活中的许多操作都是封装好的,比如ATM机,我只要按照接口操作即可,不必关心内部的具体实现。
在Java代码中如何实现封装?
Java代码实现封装的三步骤:
* 将属性设置为private
* 创建public 的 getter 和 setter方法
* 在getter/setter方法中加入属性控制语句
private关键字
使用了private关键字修饰,那么只能在类的内部进行访问
构造方法和setter
建议在使用构造函数给属性赋值的时候,也使用setter,这样就可以有对赋值的判断语句。
// 构造方法中也使用setter来进行赋值操作
public Cat(String name, int month, double weight, String species) {
this("你好");
this.setName(name);
this.setMonth(month);
this.setWeight(weight);
this.setSpecies(species);
}
包的作用:
包的作用:
* 管理Java文件
* 解决同名文件冲突
一个包内不运行存在两个同名的类,如果两个类要同名,就要在两个不同的包中。
注意:package语句必须放在程序的第一行。
因为单一职责原则,所以建议每个包内存储信息功能单一。
包的使用
如何在A包中引入B包中的类?
import com.imooc.animal.*; // * 表示导入animal中全部类
import com.imooc.animal.Cat; // 只导入annimal中的Cat类
建议采用```import 包名。类名;```的方式加载,提高效率。
同时注意,```import com.imooc.*```并不能加载全部的类!因为```import 包名.*```只能访问指定包名下的类,无法访问子包下的类。
java.lang是默认导入的包,其中有String、Math、System
如果导入的两个不同包出现了同名类,那么应该如何解决呢?
二者都使用全部路径,或者其中一方使用全路径即可。
public class Test {
public static void main(String[] args) {
// 使用全部路径导入,避免冲突
com.imooc.animal.Cat one = new com.imooc.animal.Cat();
com.imooc.mechanics.Cat two = new com.imooc.mechanics.Cat();
}
}
static修饰符
对象成员就是创建对象的时候才有,对象销毁时就会被删除。
**但是static修饰的类成员,从类创建开始就存在,直到类被销毁才消失,而且每一个对象都是使用同一个类变量,也就是说不同对象操作是同一个类成员!**
* 类对象共享
* 类加载时产生,销毁时释放,生命周期长
静态成员的访问方式
推荐通过 类.成员 的方式进行调用
one.price=200; // 对象.成员
Cat.price=200; // 类.成员
one.eat();
Cat.eat();
static修饰符使用范围
* static + 成员属性
* static + 成员方法
静态成员不能调用非静态成员,非静态成员可以调用静态成员,使用this也是不小的(从加载顺序来进行理解)
代码块
代码块
* 普通代码块: 顺序执行,先出现,先执行(可以用于处理局部变量的同名问题)
* 构造代码块:创建对象时调用,优先于构造方法执行
* 静态代码块:类加载时调用,优先于构造代码块执行
可以看到上图执行结果,静态代码块只会加载一次,而构造代码块每次新创建一个对象的时候会有加载。
**执行顺序:静态代码块>构造代码块>构造方法**