封装
面向对象的三大特性:封装 继承 多态
1.理解封装的作用
-
可以有效的解决不合理赋值的问题
-
可以降低程序之间的耦合性(牵连小)
-
可以提升代码的复用性
-
降低了大型系统的风险
2.掌握封装的使用
1.将属性私有化(添加private修饰符)
如上图,就是private修饰符了,表示私有化。
2.给属性提供对应的公共的(public) getter / setter方法
然后通过在这个类里面添加setter和getter方法,再用对象去获取。
快捷键操作步骤:Alt+Shift+S -> +R -> Alt+A -> Alt+R
比如现在有一个老师的teacher类,然后用Test去调用它
然后,在这个Teacher.java里面 按快捷键 Shift + Alt + S
如图,选择这个
跟据自己的实际需要勾选对应的属性,然后确定
系统就会帮你生成代码了,然后结合实际情况,在方法中添加逻辑控制语句
例如:
public void setHealth(int health) {
// 3.在方法中添加逻辑控制语句
if(health < 0 || health > 100) {
System.out.println("健康值非法!已经设为默认值60!");
this.health = 60;
}else {
this.health = health;
}
}
然后setter和getter方法写好以后,通过对象来获取信息
package com;
import java.util.Scanner; // 导入Scanner包
public class Test1 {
public static void main(String[] args) {
/** 创建teacher对象 */
Teacher teacher = new Teacher();
teacher.setAge(11);
teacher.getAge();
}
}
这样我就获取到了信息了
下面我们写个宠物商店案例:结合封装来实现
需求:
宠物商店 贩卖宠物狗和宠物猫
客户可以选择领养宠物狗 或者 宠物猫
客户可以选择狗的品种
客户可以选择猫的性别
最后打印购买的宠物信息
猫的代码:
package com; // 包声明
/**
*
* @author DreamingGod123
* @version 1.0 这是一个描述猫的
*/
public class Cat {
/** 宠物姓名 */
private String name;
/** 宠物健康值 */
private int health;
/** 宠物亲密度 */
private int love;
/** 宠物性别 */
private char gender;
/** 宠物自我介绍 */
public void showMyself() {
System.out.println("宠物姓名:" + name);
System.out.println("宠物健康值:" + health);
System.out.println("宠物亲密度:" + love);
System.out.println("宠物性别:" + gender);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getHealth() {
return health;
}
public void setHealth(int health) {
if (health < 0 || health > 100) {
System.out.println("健康值输入非法,已经设为默认值60!");
this.health = 60;
} else {
this.health = health;
}
this.health = health;
}
public int getLove() {
return love;
}
public void setLove(int love) {
this.love = love;
}
public char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
}
狗的代码:
package com; // 包声明
/**
*
* @author DreamingGod123
* @version 1.0 这是一个描述狗的类
*/
public class Dog {
/** 狗的名字 */
private String name;
/** 狗的健康值 */
private int health;
/** 狗的亲密度 */
private int love;
/** 品种 */
private String breed;
/** 宠物自我介绍 */
public void showMyself() {
System.out.println("宠物姓名:" + name);
System.out.println("宠物健康值:" + health);
System.out.println("宠物亲密度:" + love);
System.out.println("宠物品种:" + breed);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getHealth() {
return health;
}
public void setHealth(int health) {
if (health < 0 || health > 100) {
System.out.println("健康值输入非法,已经设为默认值60!");
this.health = 60;
} else {
this.health = health;
}
this.health = health;
}
public int getLove() {
return love;
}
public void setLove(int love) {
this.love = love;
}
public String getBreed() {
return breed;
}
public void setBreed(String breed) {
this.breed = breed;
}
}
对象的代码:
package com; // 包声明
import java.util.Scanner; // 导入Scanner包
public class Test {
public static void main(String[] args) { // main方法程序的入口点
/** 系统提示界面 */
System.out.println("欢迎来到宠物商城");
System.out.println("本商城出售各种宠物猫,宠物狗");
System.out.println("请输入你要购买的宠物:(1.宠物猫 2.宠物狗)");
/** 创建Scanner对象 */
Scanner input = new Scanner(System.in);
int choice = input.nextInt();
System.out.print("请输入宠物的姓名:");
String name = input.next();
System.out.print("请输入宠物的健康值:");
int health = input.nextInt();
System.out.print("请输入宠物的亲密度:");
int love = input.nextInt();
switch (choice) {
case 1: // 猫
System.out.print("请输入宠物的性别(1.公 2.母):");
int genderId = input.nextInt();
Cat cat = new Cat();
cat.setName(name);
cat.setHealth(health);
cat.setLove(love);
cat.setGender(genderId == 1 ? '公' : '母');
cat.showMyself(); // 自我介绍
break;
case 2: // 狗
System.out.print("请输入宠物的品种(1.腊肠犬 2.秋田犬):");
int breedId = input.nextInt();
Dog dog = new Dog();
dog.setName(name);
dog.setHealth(health);
dog.setLove(love);
dog.setBreed(breedId == 1 ? "腊肠犬" : "秋田犬");
dog.showMyself(); // 自我介绍
break;
default:
break;
}
System.out.println("感谢您的支持!欢迎下次光临!");
}
}
Java的包组织类
package
一般包名都是公司域名的倒序,比如百度吧
百度的域名是:www.baidu.com
那么java里面就应该是com.baidu.xxx
为什么使用包?
因为在同一个文件夹下,是无法存放多个同名文件内容的
因为在同一个文件夹下,如果所有文件都放在一起,无法有效进行区分和查找
如何使用包:
在定义好包以后,如果在包下定义类,类中一定要在有效代码的第一行添加package包声明
如果在不同包中使用某个类
那么一定要在使用类中声明包的导入语句。import 要引入的类地址
import 导入包声明,需要放在package声明下,类声明上的位置。
如果不这样做,JVM无法确认该类型的地址,也无法区分多个同名类型。
理解和掌握使用访问修饰符
public 公共的 (在整个项目中都能用)
private 私有的 (只能在同一个类中使用)
默认/包级(同一个包)访问修饰符(default / friendly) 什么都不加就是默认访问修饰符
protected 受保护的 和继承中的子类/父类有关
它们可以用来修饰类 方法 属性
修饰符\作用域 | 同一个类 | 同一个包 | 子类 | 项目任何地方 |
---|---|---|---|---|
private | √ | x | x | x |
默认/包级 | √ | √ | x | x |
protected | √ | √ | √ | x |
public | √ | √ | √ | √ |
static关键字
static 静态的
- static修饰的信息是属于类的,它是随着类的加载而加载的。
- 我们没有被static修饰的信息是非静态/实例的,多个实例/对象之间的信息是相互隔离。而static修饰时被多个实例共享。
- 被static修饰的信息可以直接采用类名.的形式来调用,也可以使用对象来调用
加载顺序
static可以用来修饰属性、方法,还可以用来修饰代码块。
静态代码块 -> 构造代码块 -> 构造方法
public class Student {
public String name;
public int age;
public static int classId;
// 每一次创建对象都会执行 优先构造方法执行
// 代码块/构造代码块/成员代码块/非静态代码块
{
System.out.println("构造代码块执行了!");
}
public Student(){
System.out.println("构造方法执行了!");
}
// 静态代码块 它随着类加载而出现 所以只会在【第一次】创建对象时执行
static {
System.out.println("静态代码块执行了!");
}
}