封装

1.封装

1.概念:

将类中的属性隐藏在类的内部,使用private修饰,不让外部类直接访问,提供一对公开的getter、setter方法,getter方法用于获取属性值(读取),setter方法用于设置属性值(写入)

2.封装的步骤:

​ (1)属性私有

​ (2)方法公开

3.封装的好处:

​ (1)便于使用者正确使用系统,防止错误修改属性

​ (2)降低了构建大型系统的风险

​ (3)提高程序的可重用性

​ (4)降低程序之间的耦合度

package com.qfedu.test1;

public class Student {
	private  String name;
	private int age;
	private double score;
	
	public void setName(String name) {
		this.name = name;
	}
	public String getName() {
		return name;
	}
	
	public void  setAge(int age) {
		if(age > 0 && age <= 140) {
			this.age = age;
		}else {
			System.out.println("年龄不合适,使用默认年龄");
			this.age = 18;
		}
	}
	
	public int getAge() {
		return age;
	}
	
	public void setScore(double score) {
		if(score >= 0 && score <= 100 ) {
			this.score = score;
		}else {
			System.out.println("分数不合适,使用默认分数");
			this.score = 60;
		}
	}
	
	public double getScore() {
		return score;
	}
	
	public void printStu() {
		System.out.println("学生名字是" + name);
		System.out.println("学生分数是" + this.getScore());
		System.out.println("学生的年龄是" + getAge());
	}
	
	public static void main(String[] args) {
		Student stu1 = new Student();
		stu1.name = "赵四";
		stu1.age = -20;
		stu1.score = -50;
		// 以上代码 在实际开发中不会将测试类和实体类写在一起
	}
}

2.访问权限

1.类的访问权限:

​ public:本项目中都可以访问

​ 默认不写:只在同一个包中可以访问

2.类成员的访问权限(包括属性、方法):

​ private:本类中可以访问

​ 默认不写:本类、同一个包中可以访问

​ protected:本类、同一包中、不同包的子类中可以访问

​ public:本类、同一包中、不同包的子类中、任何地方

如果在同一个类中需要访问两个同名但是不同包的类,那么可以使用全限定名(包名+类名)来访问。

3.通过eclipse编辑器观察:

​ (1)红色的方框表示私有private修饰的

​ (2)蓝色的三角表示默认修饰的

​ (3)黄色的圆角的方框是protected

​ (4)绿色的圆点表示public修饰的

作用域 修饰符同一个类中同一个包中子类中任何地方
private可以不可以不可以不可以
默认修饰符可以可以不可以不可以
protected可以可以可以不可以
public可以可以可以可以

在这里插入图片描述

3.static关键字

3.1static修饰属性

1.适用场景:

​ 修饰属性:表示此属性属于类级别的,不依托于对象而存在,将被所有的对象共享,在内存中只有一份拷贝

2.类加载的过程:

​ (1)当我们第一次访问一个类时,JVM将在方法区加载此类的class文件,并且只加载一次。(多次创建对象也是加载一次,可以简单理解为,完整运行一次,即是加载一个类一次)

​ (2)在堆中开辟一块空间,并且所有的实例变量将有默认值

​ (3)将堆中的地址赋值给栈中的引用

3.方法区:系统分配的一个内在逻辑区域,只是逻辑的概念

​ 方法区是JVM提供的一个规范,javaJVM的名字hotspot

​ JDK8之前java中的方法区叫作永久代(JVM中具体的实现)

​ JDK8之后改名为元数据(JVM中具体的实现)

4.方法区和堆:

​ 方法区和堆共享内存空间,但是方法区是静态分配内存的,我们所使用的static修饰的属性、方法,代码块都是只要类被加载,就存在的(因为不能动态回收垃圾,所以不能滥用static)。堆是随着程序的执行动态分配内存的

举例:我们的姓氏是出生就存在的,相当于静态的,我们的性格是随着成长生成的,相当于动态的。

栈:先进后出

堆:先进先出

在这里插入图片描述
在这里插入图片描述

3.2static修饰方法

static修饰的方法称之为静态方法,可以通过类名访问,不需要创建对象

1.静态方法、代码块中能不能直接访问非静态的属性和方法?

​ 不能,必须要先创建对象(有静态的,不一定有对象,而非静态是随着对象而生)

2.静态方法、代码块中能不能直接访问静态的属性和方法?

​ 可以,静态与静态之间互相可以直接访问。

3.非静态的属性和方法能不能访问静态的属性和方法?

​ 当然可以(有非静态的属性和方法当然有对象了)

package com.qfedu.test5;

public class TestStaticMethod {
	public static void m1() {
		System.out.println("静态方法1");
	}
	
	public static void m2() {
		System.out.println("静态方法2");
	}
	
	public void m3() {
		System.out.println("普通方法3");
	}
	public static void main(String[] args) {
		m1();
		TestStaticMethod tsm = new TestStaticMethod();
		tsm.m3();
	}
}
3.3static修饰代码块

被static修饰的代码块,称之为静态代码块,当JVM加载类的时候,就执行,多个静态代码块按照顺序执行,并且只执行一次,因为类只加载一次

适用场景:当我们需要做一些前置的操作,比如连接数据库,或者初始化数据。

普通代码块:直接一对大括号,只要对象创建就会被执行。
注意: 类只被加载一次,哪怕是创建N个对象,也只执行一次静态代码块

package com.qfedu.test5;

public class TestStaticCode {
	static int num = 20;
	String name;
	static {
		System.out.println("静态代码块1");
	}

	static {
		// System.out.println(name);
		System.out.println(num);
		System.out.println("静态代码块2");
	}
	
	public void m1(){
		System.out.println(num);
	}
	
	
	{
		System.out.println(num);
		System.out.println("普通代码块1============");
	}
	
	{
		System.out.println("普通代码块2=============");
	}
		
	public static void main(String[] args) {
		// 静态代码块 当我们的类被加载 就会被执行 多个静态代码块按照顺序执行 并且只执行一次
		// 用于一些前置的操作 或者 数据的初始化操作  
//		TestStaticCode tsc1 = new TestStaticCode();
//		
//		TestStaticCode tsc2 = new TestStaticCode();
//		
//		TestStaticCode tsc3 = new TestStaticCode();
		System.out.println(TestStaticCode.num);
	}	
}

4.继承

4.1extends关键字

1.实现方式:使用extends关键字

2.继承优点:实现代码重用,统一、简化程序结构

3.继承:java是单根继承的,一个类只能有一个直接父类,可以有N个间接父类。(单继承,多实现)

4.可以继承哪些内容?

​ (1)public修饰的属性和方法

​ (2)protected修饰的属性和方法

​ a.protected修饰的方法在不同包子类的情况下,只能继承,不能直接访问

​ (3)默认修饰的属性和方法,要求父子类在同包。

5.不能继承哪些内容?

​ (1)private修饰的属性和方法

​ (2)构造方法

​ (3)默认修饰的属性和方法,但是父子类不在同包。

4.2super关键字

super关键字表示父类对象,可以访问:

​ 1.父类的属性,直接super+.访问,访问规则结合访问修饰符权限

​ 2.父类的方法,直接super+.访问,访问规则结合访问修饰符权限

​ 3.父类的构造方法,super(形参列表)

​ a.子类默认访问父类的无参构造方法,除非子类显式调用父类的有参构造方法(编译器会自动在第一行插入super())

​ b.使用this关键字访问本类中的其他构造方法,将直接默认调用父类的无参构造方法此构造方法**不能调用父类的有参**(但是可以在被调用的其他本类构造方法中调用父类的构造函数,但这样用没意思啊。。。)。因为this和super在访问构造方法时,只能是用一个。都必须在构造方法的第一句。
执行顺序:
当进行无参构造时,先调用父类无参构造器,然后调用子类无参构造器;当进行含参构造时,先调用父类含参构造器,然后调用子类含参构造器

package com.qfedu.animal;

public class Pet {
	protected String name;
	protected int health;
	protected int love;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getHealth() {
		return health;
	}
	public void setHealth(int health) {
		this.health = health;
	}
	public int getLove() {
		return love;
	}
	public void setLove(int love) {
		this.love = love;
	}
	
	public Pet() {
		System.out.println("父类无参构造方法");
	}
	
	public Pet(String name,int health , int love) {
		this.name = name;
		this.health = health;
		this.love = love;
	}
	protected void print() {
		System.out.println("宠物的名字是" + this.getName() + "宠物的健康值是" + this.getHealth() + "宠物的爱心值是" + this.getLove());
	}
	
}
package com.qfedu.animal;
/**
 * 	子类访问父类的构造方法
 * 	子类默认调用父类的无参构造方法
 * 	除非子类显式的调用父类的有参构造方法
 * 	有参构造方法和无参构造方法只能调用一个
 * 	调用父类的构造方法 必须在子类构造方法的第一句
 * @author WHD
 *
 */
public class Dog extends Pet{
	
	private String strain;
	
	public String getStrain() {
		return strain;
	}
	public void setStrain(String strain) {
		this.strain = strain;
	}	
	
	public Dog(String strain) {
		this.strain = strain;
	}

	public Dog(String name,int health , int love ,String strain) {
		// this(strain);
		super(name, health, love);
		System.out.println("使用父类的构造方法初始化子类对象");
	}
	
	public Dog() {
//		super();
	}

	
	public Dog(int health,int love ,String name,String strain) {
		System.out.println("使用父类的属性初始化子类对象,使用super关键字访问父类属性");
		super.name = name;
		super.love = love;
		super.health = health;
		this.strain = strain;
	}
		
	public void printDog() {
		System.out.println("狗狗的品种是" + this.getStrain());
		super.print();
	}

}

每日问题

1.封装的作用,实现封装的步骤?
2.封装中get和set方法分别作用?
3.现有String name,int age手写实现封装
4.根据第三题提供的属性手写所有的构造方法
5.包的命名规范是什么?
6.如何在一个类中访问同名不同包的类
7.类的访问修饰符有哪些,分别代表什么意义?
8.类的成员访问修饰符有哪些,分别代表什么意义?
9.目前为止,我们学习过的内容你有哪些地方是不会的?
你认为这些知识点不会是因为什么?
10.static修饰的成员变量有什么特点,如何访问
static修饰的方法与普通方法有什么区别, /如何访问
static修饰的代码块
11.你觉得怎样预习一个新的知识点 ?

解答

1.封装的作用,实现封装的步骤?
更好的使用系统,防止错误的修改属性,降低构建大型系统的风险,降低程序的耦合
属性私有
方法公开
2.封装中get和set方法分别作用?
get获取信息
set设置值
3.现有String name,int age手写实现封装
private String name;
private int age;
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
4.根据第三题提供的属性手写所有的构造方法
public 类名(String name,int age){
this.name = name;
this.age = age;
}
public 类名(String name){
this.name = name;
}
public 类名(int age){
this.age = age;
}
5.包的命名规范是什么?
域名倒置,全部小写,不能以点开头或者结尾
6.如何在一个类中访问同名不同包的类
使用全部限定名,包名+类名
7.类的访问修饰符有哪些,分别代表什么意义?
public 表示在本项目中都可以访问
默认不写 同包中可以访问
8.类的成员访问修饰符有哪些,分别代表什么意义?
private 本类中
默认 同包中
protected 同包 + 不同包的子类
public 本项目中
9.目前为止,我们学习过的内容你有哪些地方是不会的?
你认为这些知识点不会是因为什么?
10.static修饰的成员变量有什么特点,如何访问
不依托于任何对象存在,在内存中只有一份拷贝,类名调用
static修饰的方法与普通方法有什么区别, /如何访问
静态方法,通过类名直接访问
static修饰的代码块
在加载类的时候执行,多个代码块按照顺序执行,并且只执行一次
11.你觉得怎样预习一个新的知识点 ?
这个知识点是什么?
如何实现?
为什么使用?
使用以后对比没有使用之前有什么好处?

posted on 2020-07-30 21:31  zitian246  阅读(111)  评论(0编辑  收藏  举报