文章目录
- 引出
- 概念
- 快速入门
- 对象内存布局
- 属性概念
- 创建对象访问属性
- 对象分配机制
- 成员方法
- 🦖注意事项和细节
引出
●看一个养猫猫问题
张老太养了两只猫猫: 一只名字叫小白, 今年3岁, 白色. 还有一只叫小花, 今年100岁, 花色. 请编写一个程序, 当用户输入小猫的名字时, 就显示该猫的名字, 年龄, 颜色. 如果用户输入的小猫名字错误, 则显示 张老太没有这只猫咪.
●使用现有技术解决 Object01.java
import java.util.Scanner;
public class Object01 {
//编写一个main方法
public static void main(String[] args) {
/*
张老太养了两只猫猫: 一只名字叫小白, 今年3岁, 白色. 体重, 爱好
还有一只叫小花, 今年100岁, 花色. 请编写一个程序,
当用户输入小猫的名字时, 就显示该猫的名字, 年龄, 颜色.
如果用户输入的小猫名字错误, 则显示 张老太没有这只猫咪.
//思路分析
1.单独定义变量 -> 不利于数据的管理(你把一只猫的信息拆解)
2.创建Scanner对象, 接收用户输入
*/
//代码实现
//第一只猫信息
String cat1Name = "小白";
int cat1Age = 3;
String cat1Color = "白色";
//第二只猫信息
String cat2Name = "小花";
int cat2Age = 100;
String cat2Color = "花色";
Scanner myScanner = new Scanner(System.in);
System.out.print("输入小猫的名字: ");
String catName = myScanne r.next();
//数组 ==> (1)数据类型体现不出来 (数组是多个相同类型数据的组合)
// (2)只能通过[下标]获取信息, 造成变量名字和内容的对应关系不明确
// (3)不能体现猫的行为
//第1只猫信息
String[] cat1 = {"小白", "3", "白色"}; cat1[]
String[] cat2 = {"小花", "100", "花色"};
}
}
●现有技术解决的缺点分析
不利于数据的管理
效率低 ⇒ 引出我们的新知识点, 类与对象
有很多书视频甚至还提到哲学,道家思想,形而上思想,才引出类与对象, 其实没那么复杂. java语言设计设去设计类与对象, 其实是特别简单的思想.
java设计者 引入类与对象(OOP), 根本原因就是现有的技术, 不能完美地解决新的需求
其实就是这么一点东西, 但是往往我们会把一些技术理解的过于神秘, 跟着学有关系~ 跟道家思想有关系~ 都是没有意思的
概念
一个程序就是一个世界, 有很多事物
(对象[属性, 行为])
●类与对象的关系示意图
1.把一种事物的共性(属性)提取出来,形成的一个叫做类的数据类型.
2.这个数据类型就是我们自定义的数据类型谁定义的? 程序员定义的
快速入门
●面向对象的方式解决养猫问题 Object01.java
public class Object01 {
//编写一个main方法
public static void main(String[] args) {
//使用OOP面向对象解决
//实例化一只猫[创建一只猫对象]
//解读
//1.new Cat() 创建一只猫
//2.Cat cat1 = new Cat(); 把创建的猫 赋给 cat1
//3.cat1 就是一个对象(猫对象)
Cat cat1 = new Cat();
cat1.name = "小白";
cat1.age = 3;
cat1. color = "白色";
cat1.weight = 2;
//创建第二只猫, 并赋给 cat2
//cat2也是一个对象(猫对象)
Cat cat2 = new Cat();
cat2.name = "小花";
cat2.age = 100;
cat2.color = "花色";
cat2.weight = 3;
//怎么访问对象的 属性 呢
System.out.println("第一只猫信息: " + cat1.name + " "
+ cat1.age + " " + cat1.color + " " + cat1.weight);
System.out.print("第二只猫信息: " + cat2.name + " "
+ cat2.age + " " + cat2.color + " " + cat2.weight);
}
}
//使用面向对象的方式解决养猫问题
//定义一个猫类 -> 自定义的数据类型
class Cat {
//属性
String name;//名字
int age;//年龄
String color;//颜色
double weight;//体重
//行为
}
●类和对象的区别和联系
通过上面的案例和讲解我们可以看出:
1)类是抽象的, 概念的, 代表一类事物, 比如人类, 猫类…, 即它是数据类型
2)对象是具体的, 实际的, 代表一个具体事物, 即 是实例
3)类是对象的模板, 对象是类的一个个体, 对应一个实例.
对象内存布局
●对象在内存中的存在形式
属性概念
●属性/成员变量
√ 基本介绍 Object02.java
1.从概念或叫法上看: 成员变量 = 属性 = field字段 (即 成员变量是用来表示属性的, 这里, 统一叫 属性)
2.属性是类的一个组成部分, 一般是基本数据类型, 也可以是引用类型(对象, 数组). 比如我们前面定义猫类 的 int age 就是属性.
public class Object02 {
//编写一个main方法
public static void main(String[] args) {
}
}
class Car {
String name;//属性, 成员变量, 字段 field
double price;
String color;
String[] master;//属性可以是基本数据类型, 也可以是引用类型(对象, 数组)
}
√ 注意事项和使用细节 PropertiesDetail.java
1)属性的定义语法同变量不同, 实例: 访问修饰符 属性类型 属性名;
这里简单地介绍一下访问修饰符: 控制属性的访问范围
有4种访问修饰符 public protected 默认 private, 后面再详细学习
2)属性的定义类型可以是任意类型, 包含基本类型和引用类型
3)属性如果不赋值, 有默认值, 规则和数组一样
byte 0, short 0, int 0, long 0
float 0.0, double 0.0
char ‘\u0000’, boolean false
String null
4)
public class PropertiesDetail {
//编写一个main方法
public static void main(String[] args) {
//创建Person对象
//p1 是对象名(对象引用)
//new Person() 创建的对象空间(包括数据) 才是真正的对象
Person p1 = new Person();
//对象属性的默认值, 遵守数组的规则
/*
byte 0, short 0, int 0, long 0
float 0.0, double 0.0
char ‘\u0000’, boolean false
String null
*/
System.out.println("当前这个人的信息");
System.out.println("age=" + p1.age + " name=" + p1.name + " sal=" +
p1.sal + " isPass=" + p1.isPass);
}
}
class Person {
//四个属性
int age;
String name;
double sal;
boolean isPass;
}
创建对象访问属性
●如何创建对象
1.先声明再创建
Cat cat; //声明对象 cat
cat = new Cat(); //创建
2.直接创建
Cat cat = new Cat();
●如何访问属性
√ 基本语法
对象名.属性名;
cat.name;
cat.age;
cat.color;
对象分配机制
●类和对象的内存分配机制(重要)
√ 看一个思考题 Object03.java
我们定义一个人类(Person)(包括 名字, 年龄)
我们看看下面一段代码
Person p1 = new Person();
p1.age = 10;
p1.name = “小明”;
Person p2 = p1;//把p1 赋给了 p2; 让p2指向p1
System.out.println(p2.age);
请问: p2.age究竟是多少? 并画出内存图.
public class Object03 {
//编写一个main方法
public static void main(String[] args) {
Person p1 = new Person();
p1.age = 10;
p1.name = "小明";
Person p2 = p1;//把p1 赋给了 p2; 让p2指向p1
System.out.println(p2.age);
}
}
class Person {
int age;
String name;
}
√ Java内存结构分析
- 栈: 一般存放基本数据类型(局部变量)
- 堆: 存放对象(Cat cat, 数组等)
- 方法区: 常量池(常量, 比如字符串), 类加载信息
- 示意图[Person(age, name)]
√ Java创建对象的流程简单分析
Person p = new Person();
p.name = “jack”;
p.age = 10;
1.先加载Person类信息(属性和方法信息, 只会加载一次)
2.在堆中分配空间, 进行默认初始化[看规则]
3.把地址赋给 p, p 就指向对象
4.进行指定初始化, 比如 p.name = “jack”; p.age = 10
√ 看一个练习题, 并分析画出内存布局图, 进行分析
//我们看看下面一段代码, 会输出什么信息
Person a = new Person();
a.name = “小明”;
a.age = 10;
Person b;
b = a;
System.out.println(b.name);//小明
b.age = 200;
b = null;
System.out.println(a.age);//200
System.out.println(b.age);//报错
public class Object03 {
//编写一个main方法
public static void main(String[] args) {
/*Person p1 = new Person();
p1.age = 10;
p1.name = "小明";
Person p2 = p1;//把p1 赋给了 p2; 让p2指向p1
System.out.println(p2.age);*/
Person a = new Person();
a.name = "小明";
a.age = 10;
Person b;
b = a;
System.out.println(b.name);//小明
b.age = 200;
b = null;
System.out.println(a.age);//200
System.out.println(b.age);//报错
}
}
class Person {
int age;
String name;
}
成员方法
●基本介绍
在某些情况下, 我们需要定义成员方法(简称方法). 比如人类: 除了有一些属性外(年龄, 姓名…), 我们人类还有一些行为比如: 可以说话, 跑步…通过学习, 还可以做算术题. 这时就要用成员方法才能完成. 现在要求对Person类完善.
●成员方法快速入门 Method01.java
1)添加speak 成员方法, 输出 我是一个好人
2)添加cal01 成员方法, 可以计算从 1 + … + 1000 的结果
3)添加cal02 成员方法, 该方法可以接收一个数n, 计算从 1 + … + n 的结果
4)添加getSum 成员方法, 可以计算两个数的和
public class Method01 {
//编写一个main方法
public static void main(String[] args) {
//方法使用
//1. 方法写好后, 如果不去调用(使用), 不会输出
//2. 先创建对象, 然后调用方法即可
Person p1 = new Person();
p1.speak();//调用方法
p1.cal01();//调用cal01方法
p1.cal02(5);//调用cal02方法, 同时给n = 5
p1.cal02(10);//调用cal02方法, 同时给n = 10
//调用getSum方法, 同时num1=10, num2=20
//把 方法 getSum 返回的值, 赋给 变量 returnRes
int returnRes = p1.getSum(40, 20);
System.out.println("getSum方法返回的值=" + returnRes);
}
}
class Person {
int age;
String name;
//方法(成员方法)
//添加speak 成员方法, 输出 我是一个好人
//解读
//1. public 表示方法是公开的
//2. void : 表示方法没有返回值
//3. speak() : speak是方法名 ()是形参列表
//4. {} 方法体, 可以写我们要执行的代码
//5. System.out.println("我是一个好人"); 表示我们的方法就是输出一句话
public void speak() {
System.out.println("我是一个好人");
}
//添加cal01 成员方法, 可以计算从 1 + ... + 1000 的结果
public void cal01() {
/*
可以用循环语句
1.循环1-1000
2.定义一个变量 int sum, 累积求和
*/
int sum = 0;
for (int i = 1; i <= 1000; i++) {
sum += i;
}
System.out.println("cal01方法 计算结果=" + sum);
}
//添加cal02 成员方法, 该方法可以接收一个数n, 计算从 1 + ... + n 的结果
//解读
//1. (int n) 形参列表, 表示当前有一个形参 n, 可以接收用户输入
public void cal02(int n) {
//循环完成
int sum = 0;
for (int i = 1; i <= n; i++) {
sum += i;
}
System.out.println("cal02方法 计算结果=" + sum);
}
//添加getSum 成员方法, 可以计算两个数的和
//解读
//1. public 表示方法是公开的
//2. int : 表示方法执行后, 返回一个 int值
//3. getSum 方法名
//4. (int num1, int num2) 形参列表, 2个形参, 可以接收用户传入的两个数
//5. return res; 表示把 res 的值, 返回
public int getSum(int num1, int num2) {
int res = num1 + num2;
return res;
}
}
●方法的调用机制原理
画出程序执行过程[getSum]+说明
●为什么需要成员方法 Method02.java
√ 看一个需求:
请遍历一个数组, 输出数组的各个元素值 int[][] map = {{0, 0, 1}, {1, 1, 1}, {1, 1, 3}};
√ 解决思路1: 传统的方法, 就是使用单个for循环, 将数组输出, 大家看看问题是什么?
√ 解决思路2: 定义一个类 MyTools, 然后写一个成员方法, 调用方法实现, 看看效果又如何.
●成员方法的好处
√ 提高代码的复用性
√ 可以将实现的细节封装起来, 然后供其它用户来调用即可
●成员方法的定义
访问修饰符[public…] 返回数据类型 方法名 (参数列表…) {//方法体
语句;
return 返回值;
}
1.形参列表: 表示成员方法输入 cal(int n), getSum(int num1 int num2)
2.返回数据类型: 表示成员方法输出, void 表示没有返回值
3.方法主体: 表示为了实现某一功能代码块
4.return 语句不是必须的
5.温馨提示: 结合前面的示意图, 理解.
🦖注意事项和细节
●注意事项和细节 MethodDetail.java
√ 访问修饰符 (作用是控制 方法使用的范围)
如果不写
是默认
访问修饰符. [有4种: public, protected, 默认, private]
√ 返回数据类型
1.一个方法最多只有一个返回值 [思考, 如何返回多个结果. 可以返回数组]
2.