1、类与对象
1.1 看一个养猫猫问题
张老太养了两只猫猫:一只名字叫小白,今年 3 岁,白色。还有一只叫小花,今年 100 岁,花色。
请编写一个程序,当用户输入小猫的名字时,就显示该猫的名字,年龄,颜色。如果用户输入的小猫名错误,则显示 张老太没有这只猫猫。
1.2使用之前技术解决
- 单独的定义变量解决
- 使用数组解决
1.3 现有技术解决的缺点分析
不利于数据的管理
效率低===》 引出我们的新知识点 类与对象 哲学, 道家思想
java 设计者 引入 类与对象(OOP) ,根本原因就是现有的技术,不能完美的解决新的新的需求.
1.3.1 使用数组定义:
//第 1 只猫信息
String cat1Name = "小白";
int cat1Age = 3;
String cat1Color = "白色";
// //第 2 只猫信息
String cat2Name = "小花";
dint cat2Age = 100;
String cat2Color = "花色";
//....很多猫
1.3.2 使用(面向对象)oop,定义:
//使用 OOP 面向对象解决
//定义一个猫类 Cat -> 自定义的数据类型
class Cat {
//属性/成员变量
String name; //名字
int age; //年龄
String color; //颜色
//行为
//比如爱运动 ,爱吃鱼
public void like(){
//爱吃鱼
}
}
//1. new Cat() 创建一只猫(猫对象)
//2. Cat cat1 = new Cat(); 把创建的猫赋给 cat1
//3. cat1 就是一个对象
Cat cat1 = new Cat();
cat1.name = "小白";
cat1.age = 3;
cat1.color = "白色";
//创建了第二只猫,并赋给 cat2
//cat2 也是一个对象(猫对象)
Cat cat2 = new Cat();
cat2.name = "小花";
cat2.age = 100;
cat2.color = "花色";
//怎么访问对象的属性呢
System.out.println("第 1 只猫信息" + cat1.name + " " + cat1.age + " " + cat1.color + " " + cat1.weight);
//cat2类似
1.4 类与对象的关系示意图
类就是数据类型,对象就是一个具体的实例。
1.5 类与对象的区别和联系
- 类是抽象的,概念的,代表一类事物,比如人类,猫类…, 即它是数据类型.
- 对象是具体的,实际的,代表一个具体事物, 即是实例.
- 类是对象的模板,对象是类的一个个体,对应一个实例
1.6 基本数据类型在内存中存在形式(重要的)必须搞清楚。
搞清楚这个之前先复习Java基本类型数据在内存中存在的形式。
- Java基本类型数据有8种,int,short,byte,long,float,double,char,boolean。
- 例如定义一个 int a = 3;表示 a 指向一个 int类型的引用,并且指向3这个字面值,这些字面值的数据,由于大小可知,生存期可知(这些字面值定义在某个程序块里面,程序块退出后,字段值就消失了),出于追求速度的原因,就存在于栈中。
- 并且栈数据具有共享性。例如定义两个数据 int a = 4;int b = 4;编译器先处理int a = 4;首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为4的地址,没找到,就开辟一个存放4这个字面值的地址,然后将a指向4的地址。接着再创建完b这个引用变量后,由于在栈中已经有4这个字面值,便将b直接指向4的地址。这样,就出现了a与b同时均指向4的情况。
- 但是不同于对象的地址拷贝,假如修改b的值为6,a的值不变仍然为4,不会因为b的值修改而改变。因为在修改b的值为6的时候,会重新搜索栈中是否有6的字面值,如果有那就直接将字面量为6的地址赋值给b,如果没有就会在栈中创建一个为6的字面量。因此修改b的值并不会影响a的值,a仍然指向为4的字面量。
总结:基本类型数据存在于栈中,如果两个不同变量指向相同的字面量地址,如果其中一个修改值,并不会影响另一个变量的值。
1.7 对象在内存中存在形式(重要的)必须搞清楚。
- 首先用Cat cat;声明一个对象rect时,将在栈内存为对象的引用变量cat分配内存空间。
- 但Cat的值为空,称Cat是一个空对象。空对象不能使用,因为它还没有引用任何”实体”。
- 对象实例化时的内存模型 当执行cat=new Cat(“小白”,12,“白色”);时,会做两件事:在堆内存中为类的成员变量name,age,color分配内存(字符串会定义在方法区的常量池中)。并将其初始化为各数据类型的默认值;
- 接着进行显式初始化(类定义时的初始化值);
- 最后调用构造方法,为成员变量赋值。返回堆内存中对象的引用(相当于首地址)给栈中的引用变量cat,以后就可以通过cat来引用堆内存中的对象了。
1.8属性、成员、变量
- 从概念或叫法上看: 成员变量 = 属性 = field(字段) (即 成员变量是用来表示属性的,授课中,统一叫 属性)
- 属性是类的一个组成部分,一般是基本数据类型,也可是引用类型(对象,数组)。比如我们前面定义猫类 的 int age 就 是属性
class Car {
String name; //属性, 成员变量, 字段 field
double price;
String color;
String[] master;//属性可以是基本数据类型,也可以是引用类型(对象,数组)
}
1.8.1属性、成员、变量,注意事项
- 属性的定义语法同变量,
示例:访问修饰符 属性类型 属性名;
有四种访问修饰符 public, proctected, 默认, private ,后面我会详细介绍 - 属性的定义类型可以为任意类型,包含基本类型或引用类型
- 属性如果不赋值,有默认值,规则和数组一致。
1.9案例演示
p2.age = 10,因为是地址拷贝,并且p2做出相应改变p1也会改变。
1.10 类和对象的内存分配机制
Java内存的结构分析:
- 栈:一般存放基本数据类型(局部变量)
- 堆:存放对象(Cat cat,数组等)
- 方法区:常量池(常量,比如字符串),类加载信息
Java创建对象的流程简单分析:
Person p = new Person();
p.name = “jack”;
p.age = 10
- 先加载Person类信息(属性和方法信息,只会加载一次)
- 在堆中分配空间, 进行默认初始化(看规则)
- 把地址赋给p引用p引用在栈内存中,
- p中存储的是堆内存中的地址.
- 进行指定初始化, 比如 p.name =”jack” p.age = 10
思考题
本博客引用韩顺平老师Java课程