1、封装
为了提高类的隐藏性,对类实现的细节隐藏,提供外部访问接口即可,提高代码的可扩展性
生活中的封装:例如笔记本的内部结构一封装,一般人使用笔记本时不需要了了解笔记本的结构而是直接关机
1、对类的成员属性的封装
将属性私有化(private),并提供对属性的访问给属性添加公用的getter和settr方法
2、对代码的封装
为了提高代码的复用性,尽量使用方法加参数传递对代码进行封装,并使用该方法公有(public)
public class People {
private String pname;
private int age;
private String sex;
// 提供 getter 和 setter
public String getPname(){
return pname;
}
public void setPname(String pname){
this.pname=pname;
}
public int getAge(){
return age;
}
public void setAge(int age){
// 对成员属性的隐蔽性 可以防止随意对属性更改
if(age>100 || age<0){
System.out.println("赋值的年龄不合法");
return;
}
this.age = age;
}
public String getSex(){
return sex;
}
public void setSex(String sex){
this.sex= sex;
}
// 通常为了方便给属性赋值,会提供有参构造
public People(String pname ,int age,String sex){
this.pname = pname;
this.age = age;
this.sex = sex;
}
public People(){
}
}
对于boolean类型的属性,需要使用isXxx返回属性值。
封装优点:
1、良好的封装可以减少类的耦合性(类与类的关联)
2、对类中封装的代码可以自由修改,而不会影响他类。
3、最大程度提高类中属性的隐蔽性,的对属性的控制
2、访问修饰符的权限
用于修饰类,属性,方法的关键字都称为访问修饰符
1、pudlic:公共的
可被同一个项目的所有类方法(项目可见性)
2、protected:受保护
可以被自身类访问
可以被同包下的其他访问
对于不同包,存在父子关系的子类可以访问
3、默认的
可以被自身访问
可以被同包下其他类访问
4、private:私有的
只能被自身类访问
访问修饰符 | 同一类 | 同一包不同类 | 不同包的子类 | 不同包 |
---|---|---|---|---|
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
默认 | √ | √ | × | × |
private | √ | × | × | × |
3、static关键字
static表示“静态”,它可以修饰属性,方法,代码块,在一个了一中除可以定义成员属性、成员方法和构造器以外,还可以定义静态的部分(静态属性、静态方法、静态代码块)
static修饰属性:称为静态属性或类属性
static修饰方法:称为静态方法或类方法
static修饰的语句块:称为静态代码块
static修饰的组件不需要通过对象访问,而是直接通过类名访问,在类一加载时会给static修饰的属性和方法分配内存区,这个内存分区在静态内存区中,后续所有对象操作的是同一内存区
public class Student {
// 成员属性
String name;
// 静态属性 通常static写在public的后面
static int age=20;
// 静态代码块
static{
System.out.println("这是静态代码块,在类一加载时,就会被执行,且只执行一次");
}
//成员方法 : 既可以访问 成员属性,也可以访问静态属性
public void getInfo(){
System.out.println("姓名:"+name +" 年龄:" +age);
}
// 静态方法 : 只能访问静态属性,不能访问成员属性(非静态属性
// 这是为什么? 由于成员属性的存在需要依赖对象 ,
// 静态属性和静态方法在创建对象之前就必须初始化并分配内存
public static void getStaticInfo(){
// System.out.println("姓名:"+name); 成员属性不能被访问
System.out.println("静态属性:"+age);
}
public Student(){
System.out.println("无参构造器");
}
// 构造代码块
{
System.out.println("构造代码块");
}
public static void main(String[] args) {
System.out.println("访问静态属性:"+Student.age);
// 访问静态方法
Student.getStaticInfo();
}
// 类的组件执行顺序
// 类编译成.class文件被JVM的类加载器加载-》
// 从上往下初始化static修饰的组件
// (静态属性,静态代码块,静态方法,其中静态方法调用才执行,静态属性和静态代码块直接分配内存)-》
// --》构造代码块-》执行构造器 -》初始化成员属性,成员方法
Student stu1 = new Student();
stu1.name="张三";
// 静态属性可以通过类名访问,也可以通过对象名访问
stu1.age=21;
System.out.println(stu1);
Student stu2 = new Student();
stu2.name="王麻子";
stu2.age=22;
System.out.println(stu2);
System.out.println(stu1.name);
System.out.println(stu1.age); // 22
System.out.println(stu2.name); //王麻子
System.out.println(stu2.age); // 22
System.out.println(Student.age);// 22
}
案例二: 静态的变量 在同一个内存中
public class People {
double height;
static int score;
static{
score++; // 1
}
public void setScore(){
score++; //81 86
}
public static void setScore2(){
score++;
}
public static void main(String[] args) {
People p1 = new People();
p1.score=80;//静态属性
p1.setScore();
People.score=85;
p1.height= 1.75;
People p2 = new People();
p2.setScore(); //86
p2.height= 1.80;
System.out.println(p1.score); // 86
System.out.println(p1.height); // 1.75
System.out.println(p2.score);//86
System.out.println(p2.height);// 1.80
}
}
案例三: 构造代码块和静态代码块 的执行顺序
package com.j2008.statics;
/**
* ClassName: UserInfo
* Description:
* date: 2020/10/8 11:53
*
* @author wuyafeng
* @version 1.0 softeem.com
*/
public class UserInfo {
// 关于静态的组件 从上往下执行
// 静态属性 需要先初始化 ,需要new一个对象
static UserInfo u = new UserInfo(); // 先执行构造代码块 在执行构造器
static{
System.out.println("这是静态代码块,只执行一次");
}
public UserInfo(){
System.out.println("这是无参构造器");
}
{
System.out.println("构造代码块");
}
public static void main(String[] args) {
// 结果
UserInfo u = new UserInfo();
}
}
结果:
构造代码块
这是无参构造器
这是静态代码块,只执行一次
构造代码块
这是无参构造器