文章目录
复习
面向对象和面向过程对比:
面向对象:
去饭店吃饭,找装修公司帮我们装修,找医生看病
找合适的人,做合适的事,提高效率
面向过程:
自己做饭,自己装修,自己看病
自力更生,亲力亲为
类和对象
类:
一类事物的统称,上面包含属性描述和行为描述
对象:
独立的,唯一的,特殊的,个体的!!!
乔布斯,雷布斯,李书福,罗永浩,马化腾,任正非。
Java 中定义类的格式
class 类名 {
成员变量 ==> 属性描述
构造方法 ==> 和 new 关键字联用用于目前的实例化对象/创建对象
成员方法 ==> 行为描述
}
实例化对象/创建对象格式;
类名 对象名 = new 构造方法(所需参数);
对象操作成员变量:
对象.成员变量
对象操作成员方法:
对象.成员方法(必要参数);
class Person {
// 成员变量 ==> 属性描述
int id;
String name;
int age;
// 无参数构方法
public Person() {
}
// 有参数构造方法
public Person(int i, String n, int a) {
id = i;
name = n;
age = a;
}
// 成员方法
public void sleep(int hours) {
System.out.println("每天完成睡眠" + hours + "小时");
}
public void eat(String food) {
System.out.println("中午吃" + food);
}
public void coding() {
System.out.println("键盘敲烂,月薪过万");
}
}
public class Demo1 {
public static void main(String[] args) {
Person p1 = new Person();
Person p2 = new Person(1, "张三", 20);
p1.id = 10;
p1.name = "李四";
p1.age = 15;
System.out.println("Id:" + p1.id);
System.out.println("Name:" + p1.name);
System.out.println("Age:" + p1.age);
p2.sleep(10);
p2.eat("蛋炒饭");
p2.coding();
}
}
面向对象
1. 封装
1.1 狭义的封装和广泛地封装
面向对象的封装 ==> 狭义的封装
Java 中定的类要求符合 JavaBean 规范
广泛的封装
一段代码使用了三遍,封装一个方法
一组相关的方法使用了三遍,封装了一个类
一个类使用了三遍, 完成完整的开发文档
开发文档后期阅读了三次,发一篇博客
1.2 Java 符合 JavaBean 规范封装
JavaBean 规范
规范: 码出规范,码出高效,提高代码的可复用性
要求:
1. 所有成员变量全部【私有化】
2. 所有成员变量提供对应的 【setter and getter】 方法
3. 必须提供一个无参数构造方法,其他有参数构造方法根据实际所需提供
1.21 私有化
使用关键字 private
public
公共的 公开的,可以用于修饰成员变量,成员方法,和构造方法
修饰的内容类外可以根据对应的语法要求直接使用,使用限制较少
private
私有的,可以用于修饰成员变量,成员方法,和构造方法
修饰的内容类外无法直接使用
class Person {
// public 修饰的公布成员变量 id
public int id;
// private 修饰的私有化成员变量 num 并且复制初始化数据 10
private int num = 10;
}
public class Demo1 {
public static void main(String[] args) {
Person person = new Person();
// 通过 Person 类对象 person 操作 public 修饰成员变量 id 可以使用
person.id = 10;
System.out.println(person.id);
/*
* The field Person.num is not visible
* Person 类内的成员变量 num 是不可见的,因为 num 使用 private 修饰
* 类外无法使用。
*/
System.out.println(person.num);
}
}
1.22 this 关键字
针对于目前而言 this 关键字,主要解决的问题是:
方法参数变量名称和成员变量名称一致的情况下,解决冲突问题。
/**
* 期望方法参数名称带有一定的语义性和指向性,用户可以根据参数变量的名称
*了解当前参数到底赋值给哪一个数据
*
*目前 i n a 参数名称是绝对不允许 !!!
*
*方法参数变量为 id name age 可以更好地给予程序员使用的引导,阅读性更好!!
*
*/
public SingleDong(int id, String name, int age) {
/*
* Java 编译器如果发现参数变量 或者说 方法内部定义的变量和成员变量名称一致
* 会采用就近原则,方法内部采用参数变量或者方法自定义变量,操作内容和成员变量无关.
* 通过代码的颜色可以发现,当前操作的变量颜色和成员变量颜色不同。
*
* id = id;
* name = name;
* age = age;
* 以上代码错误
*
* 【问题】
* 明确赋值号左侧的变量为成员变量
* 【解决】
* 使用 this 关键字明确当前操作变量为成员变量,不是方法参数变量
*/
this.id = id;
this.name = name;
this.age = age;
}
1.23 setter and getter 方法
功能:
setter 方法是给予私有化成员变量进行赋值操作,因为私有化成员变量无法类外直接使用,使用 setter 方法形式规范化赋值操作过程
格式:
public void set 成员变量名(对应成员变量数据类型参数) {
赋值成员变量语句;
}
案例:
private String name; // 私有化成员变量
// 注意方法名必须符合小驼峰命名法,参数数据类型和成员变量数据类型一致
public void setName(String name) {
// this.name 明确当前操作的是成员变量非参数变量
this.name = name;
}
Getter 方法功能:
getter 方法是用于获取私有化成员变量数据存储内容,因为私有化变量无法类外直接操作,使用 getter 方法形式规范法取值操作过程
格式:
public 对于成员变量数据类型返回值 get 成员变量名() {
return 成员变量;
}
案例:
private String name; // 私有化成员变量
// 方法的返回值类型和成员变量数据类型一致,方法名称必须符合小驼峰命名法
public String getName() {
return name;
}
1.24 Java Bean 规范实体化类案例
/**
* 当前类就是符合 JavaBean 规范封装的实体类
* 1. 所有成员变量全部私有化
* 2. 提供针对于所有成员变量的 Setter and Getter 方法
* 3. 必须提供一个无参数构造方法,其他有参数构造方法根据所需完成
*/
class SinglePerson {
// 成员变量
private int id;
private String name;
private int age;
// 构造方法
public SinglePerson() {
}
public SinglePerson(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
// 针对有私有化成员变量的 setter and getter 方法
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class Demo1 {
public static void main(String[] args) {
SinglePerson sp1 = new SinglePerson();
// 利用 setter 方法进行赋值成员变量操作
// sp1.id = 1;
sp1.setId(1);
sp1.setName("张三");
sp1.setAge(10);
// 利用 getter 方法取值类对象私有化成员变量数据存储信息
System.out.println("Id" + sp1.getId());
System.out.println("Name" + sp1.getName());
System.out.println("Age" + sp1.getAge());
SinglePerson sp2 = new SinglePerson(23, "李四", 50);
System.out.println("Id" + sp2.getId());
System.out.println("Nmae" + sp2.getName());
System.out.println("Age" + sp2.getAge());
}
}
2. 继承
2.1 生活中的继承
继承:
龙生龙 凤生凤 老鼠的儿子会打洞
子继父业
你长得真想你父母
继承要求:
1. 必须符合生活逻辑
2. 必须确实存在继承关系
开发中使用继承最多的地方:
游戏开发
英雄联盟:
属性:血量, 魔法值,攻击力,护甲,魔法抗性,移动速度,攻击速度, CD....
技能: QWER
英雄特征:
适合不同的角色
英雄所有的属性和技能对应一个【基类】,具备特征行的英雄继承【基类】,并且在当前基础之上进行个性化,特征化处理
针对于 Java 开发继承承担的任务
1. Java 中的继承,重点是数据类型的一致化
2. 方法的传递性和继承。
2.2 Java 中继承的基本语法
关键字:
extends
格式:
class A extends B {
}
A 类是 B 类的一个子类
B 类是 A 类的唯一父类
Java 中的继承主要关注的是
1. 类型的延续性,类型的一致性
2. 方法的传递性和继承
特征:
1. 子类可以通过继承得到父类中的非私有化成员变量和成员方法的使用/操作权利
2. 子类不可以通过继承的到父类中私有化成员变量和成员方法的使用/操作权利
2.3 继承语法演示案例代码
// 继承案例代码
class SuperClass {
// public 修饰的成员变量和成员方法
public int num = 10;
public void game() {
System.out.println("Coding~~~");
}
// private 修饰的成员变量和成员方法
private int ret = 20;
private void uniqueTech() {
System.out.println("绝活!!!");
}
}
/*
* extends 关键字完成继承操作
* SubClass 是 SuperClass 的一个子类
* SuperClass 是 SubClass 的唯一父类
*
* 子类没有任何的内容!!
*/
class SubClass extends SuperClass {
}
public class Demo2 {
public static void main(String[] args) {
SubClass sc = new SubClass();
// 子类对象可以通过继承得到父类 public 修饰的成员变量和成员方法
System.out.println(sc.num);
sc.num = 20;
System.out.println(sc.num);
sc.game();
// 通过子类对象调用父类私有化成员变量和成员方法报错!!!本身子类不具备对应方法,同时
// private 修饰的私有化内容类外无法使用
// The field SuperClass.ret is not visible
// SuperClass 类内的 private 修饰成员变量 ret 不能被访问
// System.out.println(sc.ret);
// The method uniqueTech() from the type SuperClass is not visible
// SuperClass 类内的 private 修饰成员方法 uniqueTech() 不能被 访问
// sc.uniqueTech();
}
}
2.4 继承带来的问题
合理合适的解决方案:
重写:
1. 必须存在继承关系
2. 子类重写父类方法, 要求方法声明必须一致
3. 子类可以根据特征需求,重新完成方法体实现,满足自身需求
4 必须使用 @Override 注释(注释 + 解释) 开始重写代码格式严格检查,如果子类重写父类方法,方法声明不一致,【语法报错】无法编译通过。
优势:
1. 降低了开发压力,不必要准备过多的方法,子类和父类
2.5 重写代码案例
// 继承遇到问题 ==> 重写
class Father {
public void game() {
System.out.println("黄金矿工,捕鱼达人");
}
public void work() {
System.out.println("机械工程师");
}
}
/*
Son 类是 Father 类的子类,可以继承得到父类中 public 的修饰的成员方法
目前子类没有任何内容
子类对象可以使用父类的方法,但是父类的方法执行的目标/效果,不满足,不合适子类的特殊情况
继承可以增强方法延续性, 但是父亲的方法有可能不满足子类的实际情况
方案1:
子类不考虑使用父类方法,自定义方法描述自身行为
方案 1 弊端:
会导致开发压力巨大!!需要记忆的方法很多,导致代码冗余,不便于开发操作
【重写】!!!!
*/
class Son extends Father {
/*
子类重写了父类的 game 方法, 同时根据自身情况,修改了方法体实现,满足自身需求
*/
@Override
public void game() {
System.out.println("PUBG LOL WZRY");
}
@Override
public void work() {
System.out.println("不正经讲师");
}
}
public class Demo3 {
public static void main(String[] args) {
Son son = new Son();
son.game();
son.work();
}
}
3. 多类合作 生活案例
3.1 汽车和修理厂
汽车 ==> 汽车类
属性:
品牌 颜色 轮胎个数
行为/功能:
飙车 ==> 前提,轮胎应该是 OK 的!!!
修理厂 ==> 修理厂类
属性:
店铺,地址,联系方式
行为/功能:
轮胎专修:
修汽车的轮胎
汽车是
是别人的车
汽车是一个外来数据 ==> 参数
3.2 Car. java
/**
* 汽车类
* 属性: 品牌,颜色,轮胎个数
* 行为: 飙车
*
*/
public class Car {
//成员变量
/**
* 品牌
*/
private String name;
/**
* 车身颜色
*/
private String color;
/**
* 轮胎个数
*/
private int wheelCount;
// 无参数构造方法
public Car() {}
// 初始化所有成员变量参数方法
public Car(String name, String color, int wheelCount) {
this.name = name;
this.color = color;
this.wheelCount = wheelCount;
}
/**
* 飙车方法,轮胎个数必须为 4 个数, 少一个都不行,无法飙车
*/
public void race() {
// 判断 当前汽车的轮胎个数是否为 4
if (4 == wheelCount) {
System.out.println("我开着" + color + name + "在老君山上以200 KM/h 飞驰");
} else {
System.out.println("车辆轮胎出现故障,需要修理");
}
}
// 对应私有化成员变量 Setter and Getter 方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getWheelCount() {
return wheelCount;
}
public void setWheelCount(int wheelCount) {
this.wheelCount = wheelCount;
}
}
3.3 Factory. java
package com.qfedu.c_repairCar;
public class Factory {
private String name;
private String address;
private String telephone;
public Factory() {}
public Factory(String name, String address, String telephone) {
this.name = name;
this.address = address;
this.telephone = telephone;
}
/*
* 修理汽车的方法是核心
* 当前方法所需参数是一个汽车,并且是一个外来数据,数据类型为汽车类型
* 方法执行需要修理的是一辆汽车,可以认为是 Car 类型对应的对象。
*
* 方法分析:
* public 不要问
* 返回值类型:
* void
* 方法名:
* repair
* 形式参数列表:
* (Car car)
* 表示当前方法所需的实际参数数据类型为 Car 类型
* 参数名为 car
* 方法声明:
* public void repair(Car car);
*/
/**
* 修理厂维修汽车的方法,方法参数是 Car 类型,调用执行过程中,需要提供
* Car 类型对应的对象作为实际参数
*
* @param car Car 类型
*/
public void repair(Car car) throws Exception {
// 1. 检查车辆的轮胎情况,通过 Car 类型对象调用获取轮胎个数的方法,检查轮胎情况
if (car.getWheelCount() != 4) {
// 提示轮胎有问题
System.out.println("您的轮胎有问题~~需要维修,请稍后");
Thread.sleep(1000);
// 通过 Car 类对象设置车辆的轮胎个数
car.setWheelCount(4);
System.out.println("车辆修复完成,请付款 1000 RMB");
} else {
System.out.println("您的车辆没有问题");
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
}
代码执行调用过程
/**
* 同一个包内,类可以直接调用
*
*
*/
public class Demo1 {
public static void main(String[] args) throws Exception {
// 实例化/创建一个 Car 类对象,对象名为car
Car car = new Car();
// 设置 Car 对象的属性 / 成员变量
car.setName("大众");
car.setColor("雾霾灰");
car.setWheelCount(4);
// 飙车,就是通过该 car 对象调用 race 方法,执行飙车行为
for (int i = 0; i < 10; i++) {
car.race();
// 代码运行间断 1 秒
Thread.sleep(1000);
}
System.out.println("轮胎出现问题~~~少了两个~~~");
Thread.sleep(1000);
// 轮胎个数少了两个,目前轮胎个数为 2
car.setWheelCount(2);
// 继续飙车
car.race();
// 实例化/创建Factory 修理厂对象
Factory factory = new Factory();
factory.setName("磊哥专修");
factory.setAddress("老君山上金鼎");
factory.setTelephone("138438");
/*
修理厂对象调用修理厂的成员方法 repair
同时当前所需参数为 Car 类型对象,目前代码中 Car 类型对象时 car
要什么,给什么,用什么,拿什么
【自定义类型参数作为其他方法的参数】
*/
factory.repair(car);
// 飙车,就是通过该 car 对象调用 race 方法,执行飙车行为
for (int i = 0; i < 10; i++) {
car.race();
// 代码运行间断 1 秒
Thread.sleep(1000);
}
}
}
4. 面向对象评判条件
1. 可以自定义类
2. 可以实例化/创建对象
3. 可以哦通过对象操作变量
4. 可以通过对象操作方法
System.out.println("轮胎出现问题~~~少了两个~~~");
Thread.sleep(1000);
// 轮胎个数少了两个,目前轮胎个数为 2
car.setWheelCount(2);
// 继续飙车
car.race();
// 实例化/创建Factory 修理厂对象
Factory factory = new Factory();
factory.setName("磊哥专修");
factory.setAddress("老君山上金鼎");
factory.setTelephone("138438");
/*
修理厂对象调用修理厂的成员方法 repair
同时当前所需参数为 Car 类型对象,目前代码中 Car 类型对象时 car
要什么,给什么,用什么,拿什么
【自定义类型参数作为其他方法的参数】
*/
factory.repair(car);
// 飙车,就是通过该 car 对象调用 race 方法,执行飙车行为
for (int i = 0; i < 10; i++) {
car.race();
// 代码运行间断 1 秒
Thread.sleep(1000);
}
}
}
#### 4. 面向对象评判条件
- 可以自定义类
- 可以实例化/创建对象
- 可以哦通过对象操作变量
- 可以通过对象操作方法