1. 引言
学习Java不单单要学习基础语法,也要学习编程的思想, 其中要搞明白啥是 “类” ?啥是 “对象”?还有最重要的Java的核心思想, 面向对象(oop)!
这种思想 可以把生活中的复杂的事情,变得简单化,同样也用于程序开发中,从原来的 执行者变成指挥者!
面向对象 是基于 面向过程 而言的,且二者都是编程思想!
-
面向过程 强调的是过程,是指的 动作
- 很著名的春晚小品赵本山说过: 把大象关进冰箱分几步? 1.把冰箱门打开 ; 2.把大象放进去 ; 3把冰箱门关上;
-
面向对象 强调的是结果,是 操作 对象”完成某事。
- 某平台点外卖。 不用考虑,饭怎么做,不用操心怎么来的,只需要等待送货上门就行。
- 让女朋友洗衣服,你只需要吩咐一声就可以! 不用操心具体怎么洗的,到时候等待结果就行。
上述案例的,外卖平台, 和具备洗衣服的女朋友都是指挥者操作 “对象” ! 也是java重要的思想之一!
1.1 什么是对象
-
现实世界中,随处可见的一种事物就是对象,对象是事物存在的实体。
- 例如: 周杰伦,苹果手机,北京天安门,都是所谓的对象,为什么这么说呢 ?
-
人类解决问题的方式通常都是把复杂的事物简单化,于是会思考这些对象是由什么组成的? 通常人们会将对象分为两个部分: 静态部分,和 动态部分。
-
什么是静态部分?什么是动态部分?
- 静态部分: 就是不能动的部分,称之为“属性”,任何对象都具备属性,如:人的身高, 体重,年龄,性别。
- 动态部分: 指的是某些特殊具备的行为: 如:人的,微笑,说话,行走,执行动作的部分;
-
重点:总结理解: 每个都具有3个特点: 对象的属性, 对象的行为(方法), 对象的标识(内存地址值)。
- 对象的属性: 用来描述对象的 基本特征。
- 对象的行为: 用来描述对象的 动作或者具备的功能。
- 对象的标识: 是指对象在内存中都有一个 唯一的地址用来和其他对象区分开来。(内存地址值)
-
分类是人们认识世界的一个很自然的过程,在日常生活中会不自觉地进行分类,将相近的事物归为一类,
- 例如: 人类,动物类,植物类,这一类 人或者事物都是总称。例如:人类,具体的实例化 如 张三 (属于对象,就有属性和行为)。
- 其中,对象就是 类 的实例化,是类具体的实现。
1.2. 什么是类
-
类就是同一类事物的总称。如果将现实世界中的具体一个事物抽象成对象,类就是这类对象事物的统称,如: 人类,鸟类,家禽类。
- 如: 张三,有嘴 和 四肢, 他就可以通过嘴去交谈,通过双腿走路。而基本所有的人类都具有说话和走路这个特性。
- 这样具有相同特性和行为 的一类事物就称之为 类。 类的思想就这样产生的。
-
举例子说明:看着教室的物品,说出该对象的属性和方法,并抽象出该类。
- 例如: 自行车,电动车,汽车, 属性,名称,功能就是载人,属于交通工具类。
-
总结理解: 类,是 封装 对象的属性和行为的载体,或者说, 具有相同属性和行为的一类实体称之为类。
- java中语言中基本单位 就是 类 。
- 类 是一类事物 抽取了共同属性和行为 形成的,是对象的抽象的体现。
- 类当作 设计模板。
-
注意: 类中只能定义, 方法和属性初始化,
- 不能二次赋值,或在类中使用语句! class A{int a; a=1} 就不可以!
- 在java的世界里流传这样一句话: 万物皆对象!! 你觉得它为什么这么说!?
2. 类和对象的关系
2.1 计算机怎么描述世界
- 计算机语言描述现实世界的方用 属性+ 方法(行为),
- 先创建,类,在通过 类来创建对象。
- 一个类可以创建出多个对象。
- 对象可以认为是在一类事物中抽象出某一个 特例,通过这个特例来处理这类事物出现的问题,对象可以操作类的属性和方法解决相应的问题。
- java语言是怎么来描述事物的?
-
汽车类(class ), 具体的实例为该类的对象(object),对象就具备了这个类的属性和行为,如 颜色,品牌,名称;
-
人"类": 对象,就是一个能看得到,摸得到的实体。
-
2.2 类和对象 语法结构
-
定义一个类的步骤;
-
创建对象步骤:
类名 对象名 = new 类名();
-
引用对象成员 使用
“.”
点对象名.属性 对象名.方法名();
2.3 创建类 和 调用对象
-
创建 管理员类
/**如图: * 属性:姓名 , 年龄, * 行为:介绍自己信息 */ public class Administrator{ // 1,定义类名,类的首字母一定要大写! // 2,编写属性 String name; //姓名 int age; // 年龄 // 3,定义方法 //介绍自己 public void info(){ //无返回值,无参数一个方法 System.out.println("我的名字是"+name+",年龄 "+age); } }
-
创建管理员类的实例化,即对象。
- 创建一个测试类,在测试类里创建对象。
public class TestAdmin{ // 主程序的入口 main public static void main(String[] args) { // 1.创建对象 , new关键字 实例对象 admin返回的变量引用 Administrator admin = new Administrator(); //2. 周杰伦 admin.age=34; admin.name="jaychou"; //3.方法调用 引用变量.方法名称(); admin.info(); } }
2.4 简单分析对象创建过程
Administrator admin = new Administrator();
这代码在内存中干了啥 ? 包含了两个部分:- 一,
new Administrator();
创建了该对象,并在堆内存中开辟了空间,初始化属性,生成了唯一的地址值 属性和方法作为一个整体存放在堆内存中,。 - 二,如果想使用该属性赋值,后期使用该对象,
admin = new Administrator();
返回在栈内存中的引用变量,相当于栈内存中的变量指向了堆内存中的地址值。
- 一,
3.类的方法
3.1 概述
- 方法定义: 语句的集合,它们一起执行一个功能,可以理解为对象具备的行为。
- 例如:所有的车类都会跑,只是跑的快慢有所区别,那么这个汽车会跑就是车对外提供的行为方法!还有, 鸣笛, 灯光,用方向盘转弯等。
3.2 无参数方法
-
类的无参方法分两种:有返回值类型 无参方法、 无返回值类型 无参数方法。
- 有返回值类型。
// 有返回值,有参数。 权限修饰符 返回值类型 方法名( ){ 执行方法体; return 返回值类型; // 关键字 return }
- 无返回值类型。
// 无返回值,无参数 权限修饰符 无返回值类型 方法名( ){// 无返回值类型 关键字 void 执行方法体; }
-
注意关键字:
- 如果有返回值 就返回 需要的数据类型,关键字
return
返回值类型, - return 关键字 只返回一次,相当于结束。后面不能有其他语句。
- 如果方法 没有返回值,则返回类型用关键字
void
表示无返回值类型。
- 如果有返回值 就返回 需要的数据类型,关键字
3.2.1 练习:无参数方法
- 无参数无返回值方法。关键字
void
。- 例如:玩具汽车。
- 属性:颜色,名称
- 方法: 跑。 发出声音。
public class Car {
//属性
String color;//颜色
String name; //名称
//无参数无返回值
public void run(){
System.out.println("跑起来了");
}
public void call(){
//调用属性
System.out.println(color+ "的车,我的名字叫 "+name);
}
}
- 测试类
public class Car_Test {
public static void main(String[] args) {
//1.实例化对象
Car car = new Car();
//2. 给属性赋值
car.color="红色";
car.name="法拉利";
//3.调用方法
car.run();
car.call();
}
}
-
无参数有返回值方法。关键字
return
。- 例如:“人类”
- 属性: 名字,年龄
- 方法:交谈
public class Person { //属性 String name; //姓名 int age;//年龄 //无参数有返回值 public String talk(){ //需要返回String数据类型的返回值 String s ="我的名字叫"+name+" 今年 "+age+" 岁了"; return s; // System.out.println("");//return 后面不允许有其他语句相当于结束。 } }
-
测试类
public class Person_Test { public static void main(String[] args) { Person p = new Person(); p.name="王一博"; //假设我age没有赋值,默认初始化 0; String talk = p.talk();//会有返回类型 System.out.println(talk);//我的名字叫王一博 今年 0 岁了 } }
3.2.1 练习:计算器加和减法
- 写一个计算器,求两个数的,自己完成。
- 求两个数的和。
- 求两个数的差。
- 要求:使用无返回值无参方法 和 有返回值无参方法。
// 要求: 使用无返回值无参方法 和 有返回值无参方法。
3.3 有参数方法
- 在我们日常生活中,完成某一项操作是有前提的,需要提供数据或者材料,
- 巧妇难为无米之炊,在会做饭, 没米不行。
- 榨汁机榨东西,根据放放入材料,出相应果汁。
- 带参数方法可以理解为: 例如:榨汁机。
- 接收外界提供材料 (方法参数)。
- 方法内部对数据进行加工 (方法逻辑处理)。
- 产品产出 (返回数据类型)。
- 类的有参方法分两种:有返回值类型 有参方法、 无返回值类型 有参数方法。
- 有返回值类型的有参数方法。
//有返回值类型 有参数
权限修饰符 返回值类型 方法名(参数1,参数2,参数3... ){
执行方法体;
return 返回值类型;
}
- 无返回值类型的有参数方法。
//无返回值类型 有参数
权限修饰符 无返回值类型 方法名(参数1,参数2,参数3... ){
执行方法体;
}
- 参数可以有一个,也可以有多个,可以相同类型,也可以不同类型。
- 实际参数 和 形式参数;
- 形参: 方法()里参数列表里参数叫 形式参数;
- 实参: 对象·方法名()传递的参数叫做:实际参数;例如: 形参 String name; 实参 : “周杰伦”
- 形参的定义要必须与 实参的 个数保持一致,并且传递参数的 顺序要保持一致!
3.3.1 练习:有参数方法
-
有参数有返回值,和 有参数无返回值。
- 例如:定义管理员类
- 属性:登录系统用户名,登录系统用户密码
- 方法:验证密码,提示登录成功或失败。
public class Administrator { String system_User=="admin"; //用户名,直接初始化 int sys_password==1234; // 数字4位数 Boolean flag;//登录信息 成功返回 true,失败返回false; //登录系统信息 ,有参数无返回值 public void login(boolean flag){ if (flag==true){ System.out.println("登录成功"); }else { System.out.println("登录失败"); } } //验证登录信息 有返回值有参数 public Boolean check(String user,int password){ //校验登录信息 if (user.equals(system_User)&&password==sys_password){ return true; //登录成功 }else { return false; //登录失败 } } }
-
测试类
Admin_Test.class
public class Admin_Test { public static void main(String[] args) { //1. 控制台输入用户名和密码,进行系统校验 System.out.println("请输入用户名: "); String user = new Scanner(System.in).next(); System.out.println("请输入密码: "); int password = new Scanner(System.in).nextInt(); //2.创建类的实例化对象 Administrator admin = new Administrator(); //3.调用方法 Boolean check = admin.check(user, password);//调用验证方法,注意传递参数顺序和个数 admin.login(check);//得到结果调用提示信息方法 } }
3.3.2 练习:计算器 除和乘法
- 写一个计算器,求两个数的,自己完成。
- 求两个数的除法。
- 求两个数的乘法。
- 要求:使用无返回值有参方法 和 有返回值有参方法。
// 要求: 使用无返回值有参方法 和 有返回值有参方法。
3.4 方法的调用
3.4.1 语法结构
-
对象名 . 方法名();
Person p = new Person(); //方法调用 p.talk();
3.4.2 方法之间的调用
- 上面方法里面可以调用属性,而且 方法之间也可以调用。
public class Persop {
public void like1(){
System.out.println("喜欢男生");
}
public void like2(){
System.out.println("喜欢女生");
}
// 3.方法里面也可以调用方法。
public void like3(){
Persop persop = new Persop(); //通过类的实例化对象。
persop.like();
persop.like2();
}
}
3.5 课堂案例
3.5.1. 求平均成绩 和 总成绩
- 有三门功课语文,英语,数学,键盘接收三门课程成绩,要求算出总成绩, 和 平均成绩。
- 属性: 语文,数学,英语。
- 定义方法: 求总成绩方法, 平均成绩方法。
public class ResultDemo {
// 程序入口 main
public static void main(String[] args) {
//创建对象
Result r = new Result();
// 调用对象中的方法 r·方法
Scanner input = new Scanner(System.in);
System.out.println("请输入英语成绩:");
r.english = input.nextDouble();
System.out.println("请输入数学成绩:");
r.maths = input.nextDouble();
System.out.println("请输入语文成绩");
r.chinese = input.nextDouble();
//调用平均成绩方法
double avg = r.avg();
System.out.println("您的平均成绩为:"+avg);
//调用求和成绩方法
double sum = r.sum();
System.out.println("您的总成绩为: "+sum);
}
}
/**
* 创建一个结果类
*/
class Result{
double english; // 英语成绩
double chinese; //语文成绩
double maths; // 数学成绩
/*求平均值, 有返回值类型,无参数*/
public double avg(){
double sum = english+chinese+maths;
return sum/3;
}
/*求和, 有返回值类型,无参数*/
public double sum(){
double sum = english+chinese+maths;
return sum;
}
}
输出结果:
请输入英语成绩:
80
请输入数学成绩:
20
请输入语文成绩
100
您的平均成绩为:66.66666666666667
您的总成绩为: 200.0
3.5.2. 添加用户,显示用户
-
定义用户类,要求使用 数组存储用户名称。
- 方法: 增加用户姓名,显示用户姓名。
public class User { //1.定义存储用户信息数组 String[] user_Name = new String[10]; //1.1 初始化信息 { user_Name[2]="隔壁老吴";//提前存储信息 } //2.定义方法 //2.1 添加用户方法 public void addName(String name){ for (int i = 0; i <user_Name.length ; i++) { //2.2 添加信息时不能覆盖原来的信息 //TODO 怎么不能覆盖原来信息 if (user_Name[i]==null){ //不覆盖原来信息 user_Name[i]=name; // 注意程序控制。为什么要加break ? break;//一定要跳出。否则 填满将为null元素填满。 } } } //2.2 显示方法 public void show_UserName(){ //遍历数组信息 for (int i = 0; i <user_Name.length ; i++) { //TODO 没有存储的数据就不要显示 if (user_Name[i]!=null){ System.out.println(user_Name[i]); } } } public static void main(String[] args) { User u = new User(); //调用添加方法 u.addName("张三"); u.addName("李四"); u.addName("王五"); //会覆盖隔壁老吴么?为什么? u.addName("赵六"); //显示数组数据 u.show_UserName(); } }
-
输出结果:
张三 李四 隔壁老吴 王五 赵六
3.5.3. 查询用户是否存在(多个参数)
- 需求在 4.5.2 案例 添加用户,显示用户 上增加,可以根据区间查询用户名称;
- 如果查询到就返回true 反之 返回false;
public class User {
//1.定义存储用户信息数组
String[] user_Name = new String[10];
//1.1 初始化信息
{
user_Name[2]="隔壁老吴";//提前存储信息
}
//2.定义方法
//2.1 添加用户方法
public void addName(String name){
for (int i = 0; i <user_Name.length ; i++) {
//2.2 添加信息时不能覆盖原来的信息
//TODO 怎么不能覆盖原来信息
if (user_Name[i]==null){ //不覆盖原来信息
user_Name[i]=name;
break;//一定要跳出,否则全是第一个信息。
}
}
}
//2.2 显示方法
public void show_UserName(){
//遍历数组信息
for (int i = 0; i <user_Name.length ; i++) {
//TODO 没有存储的数据就不要显示
if (user_Name[i]!=null){
System.out.println(user_Name[i]);
}
}
}
/**
* 增加显示方法,
* @param begin 开始索引
* @param end 结束索引
* @param name 查询名称
* @return boolen
*/
public boolean seachName(int begin,int end,String name){
//返回标识
for (int i = begin; i <end ; i++) { //开始为0,结束为end为100可以么?
if (i<10&&name.equals(user_Name[i])){ //i的值不能超过数组元数个数
System.out.println("查询索引为"+i); //显示查询索引
return true; //返回即程序结束。
}
}
return false;
}
public static void main(String[] args) {
User u = new User();
//调用添加方法
u.addName("张三");
u.addName("李四");
u.addName("王五"); //会覆盖隔壁老吴么?为什么?
u.addName("赵六");
//显示数组数据
u.show_UserName();
boolean flag = u.seachName(80, 100, "隔壁老吴");//这样可以么
System.out.println(flag);
}
}
5. 成员变量 和 局部变量
5.1 变量的作用域
-
还记得什么是变量吧?怎么声明一个变量?
- 变量类型 变量名 = 变量值。
-
Java中声明变量的位置不同,在访问的时候也是有差别的,这个叫做 变量的作用域。
- 作用域不同,表示变量使用范围不一样。
-
变量声明的位置,可以决定 变量的作用域,即生效范围, 怎么理解这句话呢?
-
我们可以先通过生活中的例子来理解这句话。
- 中华人名共和国法律 ----- 针对的是在中国境内的人。(包括,中国人和外国人)
- 女朋友的手机内容 ----- 她自己。
- 平台会员商品----- 只有会员才能买!非会员够买不了!
5.1.1 成员变量
- 在Java,类中定义的 属性 也称为成员变量。
- 位置: 定义在类中, 方法外,声明的变量。可以在本类中任意位置使用,即全局有效!!
- 特点: 不用初始化赋值,会自动初始化,有默认值; 整数类型 默认 0; String 默认 null;布尔类型 boolean 默认为 false;
- 生命周期: 随着类消失 ,成员变量才会消失(被GC垃圾回收清理);
- 代码中的位置:
public class VarDemo { /*定义在类里,方法外的成员变量*/ String name; // 姓名 int age; //年龄 double price; //价格 String adress; // 地址 /*程序入口 main方法, 也是方法*/ public static void main(String[] args) { } }
5.1.2 局部变量
-
定义在方法里,那么这个变量称为局部变量。
- 位置: 定义在类中,方法内,声明的变量。只能在方法中有效。
- 特点: 在该变量使用时,必须初始化来分配内存空间,即必须赋值;如: int num = 8;
- 生命周期: 方法执行时创建,方法运行后释放!
-
代码中的位置:
public static void main(String[] args) { String s = "我是定义在方法里面的局部变量"; System.out.println(s); // 局部变量使用时必须赋值; }
5.2 成员变量和局部变量的区别总结
- 在类中的位置不同,
- 成员变量:一个在类中。
- 局部变量:一个在方法中,例如: if语句。
- 在内存中不同,
- 成员变量:在堆中。
- 局部变量,在栈中。
- 生命周期不同,
- 成员变量:随着对象的创建而存在,随着对象的消失而消失。
- 局部变量:随着方法的调用而存在,随着方法的调用完毕而消失。
- 初始化值不同,
- 成员变量:有默认值 。
- 局部变量: 没有默认值必须定义,赋值才能使用。
5.3 测试局部变量和成员变量
-
看看二者的作用范围 。
public class Var { //1.定义成员变量, //?这些变量谁能使用? String name; int age; //2.定义方法 public void say(){ String chinese ="中国话才是最吊的"; int age=18; System.out.println(chinese+"我的年龄是 "+age); } //3.类中只能定义成员变量和方法,语句不能在类中定义只能在方法中 public static void main(String[] args) { for (int i = 0; i <10 ; i++) { System.out.println(i); } //这个位置能使用i的值么? System.out.println(i); Var var = new Var(); var.age=88;//给年龄赋值 var.say();// 输出的年龄是18还是88; } }
6. 小结: 银行账户练习
- 模拟银行存款业务,主要有3个业务
- 存款 。
- 取款 。
- 定义银行类。
- 属性,账户金额 (权限私有化 private)
- 方法,存款,取款。
public class Bank {
//1. 属性账户 权限问题
private double money;
//1.1 如果权限私有的话,对外就需要提供访问的方法;get 和 set方法(省略)。
public double getMoney() {
return money;
}
/**
* 2. 第一个业务方法 存款=存钱+账户余额
*
* @param cash 存款
*/
public void saveMoney(double cash) {
//2.1 存款
money = money + cash;
System.out.println("存款金额: "+cash);
}
/**
* 3.取钱方法
* @param cash 取现金
*/
public void quMoney(double cash) {
//1.判断账户余额是否购取款金额
if (money >= cash) {
money = money - cash;//取款
System.out.println("取款金额是" + cash);
} else {
System.out.println("账户余额不足");
}
}
}
- 测试类 BankTest
public class BankTest {
public static void main(String[] args) {
Bank bank = new Bank();
// bank.saveMoney(500);
// bank.quMoney(300);
// 也可以加一个 do{}while(flag); 正一个循环
System.out.println("请问您要办理的业务: 1 存款 2 取款 0退出");
//等值判断
int num = new Scanner(System.in).nextInt();
switch (num){
case 1:
//TODO
System.out.println("请输入您的存款金额:");
double m = new Scanner(System.in).nextDouble();
bank.saveMoney(m);//存款
//调用显示余额方法
double money = bank.getMoney();
System.out.println(money);
break;
case 2:
System.out.println("请您输入取款金额:");
double m2 = new Scanner(System.in).nextDouble();
bank.quMoney(m2);
//调用显示余额方法
double money = bank.getMoney();
System.out.println(money);
break;
case 0:
System.out.println("谢谢光临");
break;
default:
System.out.println("您选择的有误,请看提示");
break;
}
}
}
输出结果:
请问您要办理的业务: 1 存款 2 取款 0退出
1
请输入您的存款金额:
800
存款成功,您的余额为800.0