Java中的封装
什么是封装:将类的某些信息隐藏在内部同时提供访问接口
例子:ATM机对钞票的隐藏,但是提供了接口
实现封装的步骤:
1.修改属性的可见性:将变量设为private
2.创建getter/setter方法:设为public用于属性的读取
3.在getter/setter方法中对属性值进行判断
例子:创建一个学生类,类中将学生的姓名、性别和年龄设为隐藏属性,同时提供对这些隐藏属性的接口
public class Student{
private String name;
private String gender;
private int age;
public Student(){
}
public Student(String name, String gender, int age){
this.setName(name);
this.setGender(gender);
this.setAge(age);
}
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void setGender(String gender){
// 在setter方法中判断传递过来的性别是否正确,如果不正确就将性别默认设置为男性
if(gender.equals("男") || gender.equals("女"))
this.gender = gender;
else
this.gender = "男";
}
public String getGender(){
return this.gender;
}
public void setAge(int age){
// 对传递进来的年龄进行判断
if(age<=0 || age >=120)
System.out.println("年龄必须在1-120范围内!");
else
this.age = age;
}
public int getAge(){
return this.age;
}
}
Static的用法
static修饰的成员通常被称为静态成员或者类成员,在类首次加载时产生,类彻底消亡时释放。
static + 属性:静态属性(类属性)
static + 方法:静态方法(类方法)
static修饰的属性或者方法的访问方式有两种:
1.通过`类名.属性`或者`类名.方法`来访问
2.通过`实例对象.属性`或者`实例对象.方法`访问
下面的代码需要格外注意!
Student类:
public class Student{
private static int age;
public void setAge(int age){
// 没做age的检查
this.age = age;
}
public int getAge(){
return this.age;
}
public String studentInfo(){
String str = "学生的年龄为:" + this.getAge();
return str;
}
}
StudentTest类:
public class StudentTest{
public static void main(String[] args){
// 测试Student 类
Student stu1 = new Student();
stu1.setAge(20);
System.out.println(stu1.studentInfo());
Student stu2 = new Student();
stu2.setAge(30);
System.out.println(stu2.studentInfo());
System.out.println("========================================");
System.out.println(stu1.studentInfo());
}
}
运行后输出的结果如下:
为什么明明给stu1的年龄赋值为20,stu2的年龄赋值为30,到最后stu1的年龄也变了呢?这是因为用static修饰的成员共用一块内存空间,所以stu1的age和stu2的age实际上用的是同一块空间,当stu2设置age时会将stu1设置的age给覆盖掉!
注意:
1.static不能添加在class前,比如`public static class Student`这样的写法是错误的
2.static不能修饰方法内的变量
代码块:在{}
中间的代码块
代码块的分类:
- 普通代码块:在方法中定义,顺序执行,先出现先执行
Student类:
public class Student{
public void info(){
//代码块1
{
// 代码块2
int temp = 1;
System.out.println("代码块2中的temp=" + temp);
}
{
// 代码块3
int temp = 2
System.out.println("代码块3中的temp=" + temp);
}
}
}
StudentTest类:
public class StudentTest{
public static void main(String[] args){
Student stu1 = new Student();
stu1.info();
}
}
需要注意的是:普通代码块定义的变量会在这一代码块执行完成后销毁,而包含普通代码块的方法中定义的变量的作用域是从定义开始到方法结束。
所以下面的代码会报错:
public class Student{
public void info(){
//代码块1
int temp = 3;
{
// 代码块2
int temp = 1;
System.out.println("代码块2中的temp=" + temp);
}
{
// 代码块3
int temp = 2
System.out.println("代码块3中的temp=" + temp);
}
}
}
- 构造代码块:在类中定义,比构造法方法先执行,并且没实例化一个对象都要执行一次
Student类:
public class Student{
public Student(){
System.out.println("我是构造方法");
}
{
System.out.println("我是构造代码块");
}
}
StudentTest类:
public class StudentTest{
public static void main(String[] args){
Student stu1 = new Student();
Student stu2 = new Student();
}
}
可以看到上面代码的执行结果为:
- 静态代码块:在构造代码块前面加上static关键字修饰的代码块,在类加载时调用,优先于构造代码块,且无论实例化多少个对象只执行一次
Student类:
public class Student{
public Student(){
System.out.println("我是构造方法");
}
{
System.out.println("我是构造代码块");
}
static{
System.out.println("我是静态代码块");
}
}
StudentTest类
public class StudentTest{
public static void main(String[] args){
Student stu1 = new Student();
Student stu2 = new Student();
}
}
运行结果如下:
Java中的包管理
Java中包的作用:
1.管理java文件
2.解决同名文件的冲突
注意事项:
1.Java中一个包内不能存在同名的类
2.package语句必须位于源文件的第一行,且只能由一个package语句
3.每个包内存放单一功能的类
4.使用不同包中的类时需要使用import语句导入
5.加载类的顺序和import 语句的位置无关
6.import 包名.*只能访问该包下直接的类,无法访问该包的子包中的类
Java中常用的包:
1.java.lang包:包含java语言基础的类,默认导入。如System、String、Math
2.java.util包:常用工具包,如Scanner、Random
3.java.io包:包含输入、输出相关功能的类,如File、InputStream