封装

1.封装

1.1概念和思想

思想:我们之前直接使用等号给属性赋值,这样非常不合理,如果用户赋值了一些错误的值,我们没有机会去处理,相当于程序有比较高的耦合度,我们应该降低程序的耦合度,使用封装来解决。
封装 :
1.将类的信息尽可能的隐藏在类的内部 不让外部直接访问,使用private修饰属性即可,被private修饰的属性表示只能在本类中访问 其他类不能访问
2.而是提供一对公开的getter和setter方法用于访问属性

public class Penguin {
	private int health;
	private String sex;
	private String name;
	public  int  getHealth(){
		return health;
	}
	public void setHealth(int health) {
		if(health >=0 && health <= 100) {
			this.health = health;
		}else {
			System.out.println("健康值赋值不合理,将使用默认值60");
			this.health = 60;
		}
	}
	public void setName(String name) {
		
		
		this.name = name;
	}
	public String getName() {
		return name;
	}
	public void setSex(String sex) {
		if(sex.equals("雌") || sex.equals("雄")) {
			this.sex = sex;
		}else {
			System.out.println("性别不合适,使用默认性别雌性");
			this.sex = "雌";
		}
	}
	public String getSex() {
		return sex;
    }
}

2.访问权限修饰符

2.1类的访问权限修饰符

1.public:本项目中任何位置都可以访问
2.默认不写:本包中可以访问

2.2类成员的访问权限修饰符

1.private:表示私有的,本类中可以访问
2.默认不写:表示本包中可以访问
3.protected:受保护的,本类中,本包中,子类中
4.public:本项目中任何位置都可以访问

public class Note {
	private String field1;
	String field2;
	protected String field3;
	public String field4;
	
	private void m1() {}
	
	void m2() {}
	
	protected void m3() {}
	
	public void m4() {}
	
	
	public static void main(String[] args) {
		A a = new A(); // 同类中
		
		Note note = new Note();
		System.out.println(note.field1); // 红色方框  私有
		System.out.println(note.field2); // 蓝色三角  包级别
		System.out.println(note.field3); // 黄色菱形 受保护的 本类 本包 子类
		System.out.println(note.field4); // 绿色原点 最大范围 public
	
		note.m1();
		note.m2();
		note.m3();
		note.m4();
	}
}
    class A{
	
}
public class Test {
	public static void main(String[] args) {
		A a = new A(); // 同包中 可以访问
		// 访问属性
		
		Note note = new Note();
		System.out.println(note.field2);
		System.out.println(note.field3);
		System.out.println(note.field4);
		
		note.m2();
		note.m3();
		note.m4();
		
	}
}
public class Test {
	public static void main(String[] args) {
        //		A a = new A(); 因为A是包级别的访问权限 所以不同包不能访问
		Note note = new Note();
		System.out.println(note.field4);
		
		note.m4();
	}
}

3.static关键字

3.1 static适用场景

成员变量:静态变量,可以直接通过类名访问
成员方法:静态方法,可以直接通过类名访问
代码块:静态代码块,当Java虚拟机加载类时,就会执行该代码块

3.2 static修饰变量

被static修饰的变量在内存中只有一个拷贝,可以用于数据共享,实现多个实例之间的数据传递
在类内部,可在任何方法内直接访问静态变量
在其他类中,可以直接通过类名访问

public class Person {
	static int capacity = 10000; // 容量 1000毫升水
	String name; // 名字
	
	public void getWater() {
		if(capacity > 0) {
			capacity -= 200;
			System.out.println(name + "接水200毫升,还剩下" + capacity + "毫升");
		}else {
			System.out.println("没水了,请换水");
		}
		
	}
	
}
public class TestPerson {
	public static void main(String[] args) {
		Person zhaosi = new Person();
		zhaosi.name = "赵四";
		zhaosi.getWater();
		
		Person guangkun = new Person();
		guangkun.name = "广坤";
		guangkun.getWater();
		
		Person xiaobao = new Person();
		xiaobao.name = "小宝";
		xiaobao.getWater();
		// 问题2:我们发现不能按照设想将水容量这个数据共享
		// 因为capacity是实例变量 每new一个对象在内存中就 存在一份
		// 所以我们new三个对象 内存中有三个capacity  值都为1000
		
	}
}
public class Voter {
	static int ticketCount = 100;
	String name;
	
	public boolean voteFor() {
		if(ticketCount > 0) {
			ticketCount --;
			System.out.println(name + "投了一票,还剩余" + ticketCount);
			return true;
		}else {
			System.out.println("投票完毕请等待 下一届");
			return false;
		}
	}
	public static void main(String[] args) {		
		for (int i = 1; i < 120; i++) {
			Voter v = new Voter();
			v.name = i + "号选民";
			if(!v.voteFor()) {
				break;
			}
		}
	}
}

3.3 static修饰方法

静态方法:可以直接通过类名访问
静态方法中不能使用this和super,不能直接访问所属类的实例变量和实例方法,可直接访问类的静态变量和静态方法
实例方法:通过实例访问
可直接访问所属类的静态变量、静态方法、实例变量和实例方法
静态方法必须被实现

public class TestStaticMethod {
	
	public void m3() {
		m1();
	}
	public void m1() {
		m2(); // 直接调用 因为实例方法m1可以调用的时候 类一定被加载过了 
		// 静态方法已经初始化过了
		System.out.println("普通方法m1");
	}
	
	public static void m2() {
//		m1(); 不能直接调用m1 必须先new对象 
//		因为m2方法初始化的时候 m1方法不一定存在(必须依赖对象而存在)
		System.out.println("静态方法m2");
	}
	
	public static void main(String[] args) {
		TestStaticMethod.m2();
		TestStaticMethod tsm = new TestStaticMethod();
		tsm.m1();
	}
}
public class Test1 {
	public static void main(String[] args) {
		TestStaticMethod tsm = new TestStaticMethod();
		tsm.m1();
		TestStaticMethod.m2();
		tsm.m3();
	}
}

3.4 static修饰代码块

静态代码块:随着类被加载执行,多个静态代码块按照书写顺序执行,每个只执行一次,因为类只加载一次
静态代码块用于实现一些前置的操作,比如数据初始化等
普通代码块:每new一次对象执行一次

public class TestStaticCode {
	static int num = 10;
	static {  //静态代码块
		System.out.println("静态代码块1");
	}
	
	static {
		System.out.println("静态代码块2");
	}
	
	{  //普通代码块
		System.out.println("实例代码块1");
	}
	
	{
		System.out.println("实例代码块2");
	}

	public static void main(String[] args) {
		System.out.println(num);
		TestStaticCode tsc1 = new TestStaticCode();
		TestStaticCode tsc2 = new TestStaticCode();
		TestStaticCode tsc3 = new TestStaticCode();
	}
	
}

3.5访问规则

1.静态访问与静态访问之间调用时直接调用
2.静态访问和非静态访问调用之前必须先new对象
3.非静态的访问静态的,直接调用

4.类加载的过程

4.1名词解释

方法区:是JDK提供的一个规范,符合这个规范的即可称之为方法区
元空间:方法区的实现,JDK1.8叫元空间,用来加载类信息文件,初始化静态相关信息等。
永久代:JDK1.7之前叫永久代,方法区的实现

4.2加载过程

1.当我们第一次访问一个类时,JVM先在方法区查看是否有加载当前类信息文件,如果有,在堆中开辟空间,将栈中的引用指向堆中的空间;如果没有,先加载类信息文件,然后在堆中开辟空间,将栈中的引用指向堆中的空间。

posted @ 2021-07-24 14:25  码丁XIA  阅读(70)  评论(0)    收藏  举报