Java基础 | Java封装 | 03

封装的概念和特点

Java基础 | Java封装 | 03

封装

  • 隐藏对象的信息
  • 留出访问接口

其实生活中的许多操作都是封装好的,比如ATM机,我只要按照接口操作即可,不必关心内部的具体实现。

封装的代码实现

Java中的如何实现封装呢?主要通过以下三个步骤。

Java基础 | Java封装 | 03

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封装 | 03

Java中包的作用就是类似操作系统中文件夹的作用,包就是用来管理类文件的。

包的作用:

  • 管理Java文件
  • 解决同名文件冲突

注意:package语句必须放在程序的第一行。

因为单一职责原则,所以建议每个包内存储信息功能单一。

Java基础 | Java封装 | 03

Java基础 | Java封装 | 03

如何在A包中引入B包中的类?

import com.imooc.animal.*; // * 表示导入animal中全部类
import com.imooc.animal.Cat; // 只导入annimal中的Cat类

建议采用import 包名。类名;的方式加载,提高效率。

同时注意,import com.imooc.*并不能加载全部的类!因为import 包名.*只能访问指定包名下的类,无法访问子包下的类。

Java基础 | Java封装 | 03

Java基础 | Java封装 | 03

Java基础 | Java封装 | 03

如果导入的两个不同包出现了同名类,那么应该如何解决呢?

二者都使用全部路径,或者其中一方使用全路径即可。

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关键字

Java基础 | Java封装 | 03

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修饰的类成员,从类创建开始就存在,直到类被销毁才消失,而且每一个对象都是使用同一个类变量,也就是说不同对象操作是同一个类成员!

  • 类对象共享
  • 类加载时产生,销毁时释放,生命周期长

Java基础 | Java封装 | 03

静态成员的访问方式

推荐通过 类.成员 的方式进行调用

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

Java基础 | Java封装 | 03

可以看到上图执行结果,静态代码块只会加载一次,而构造代码块每次新创建一个对象的时候会有加载。

  • 无论产生多少类实例,静态代码块只会执行一次
  • 仅希望执行一次的代码可以放在静态代码块中

执行顺序:静态代码块>构造代码块>构造方法

小结

封装

封装

*   隐藏对象的信息
*   留出访问接口

其实生活中的许多操作都是封装好的,比如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也是不小的(从加载顺序来进行理解)

代码块

代码块

*   普通代码块: 顺序执行,先出现,先执行(可以用于处理局部变量的同名问题)
*   构造代码块:创建对象时调用,优先于构造方法执行
*   静态代码块:类加载时调用,优先于构造代码块执行

可以看到上图执行结果,静态代码块只会加载一次,而构造代码块每次新创建一个对象的时候会有加载。

**执行顺序:静态代码块>构造代码块>构造方法**