对象思想
1.什么是面向过程,什么是面向对象?
换而言之,==面向对象思想实际就是将整体分成一个个独立的单元,每个单元都有自己得任务和属性,所有单元结合在一起完成一个整体。==如果某个单元出现了问题还可以及时处理,这样的优点就是各单元间互不干扰。
面向过程就好比把事情的处理看作一个整体,一个整体是一个单元,比如串联电路思想。
面向对象三大特征:
- 封装、
- 继承、
- 多态
类与对象
变量回顾
变量:
-
局部变量 只在方法体中有效
-
成员变量
分为两类:静态变量和实例变量实例变量就是对象的属性
类与对象
一、类
- 类的定义与使用
-
定义类的语法格式:
[修饰符列表] class 类名{
*** 类体 = 属性 + 方法;
*** // 属性(实例变量),描述的是状态
*** // 方法,描述的是行为动作
} -
为什么要定义类?
因为要通过类实例化对象。有了对象,让对象和对象之间协作起来形成系统。 -
一个类可以实例化多个java对象。(通过一个类可以造出多个java对象。)
-
实例变量是一个对象一份,比如创建3个学生对象,每个学生对象中应该都有name变量。
public class Student {
// 属性:姓名,年龄,性别,他们都是实例变量
// 姓名
String name;
// 年龄
int age;
// 性别
boolean gender;
}
上述代码是否发现了个问题;
变量没有赋值唉!!!!!!
请注意:
没有赋值不能使用的变量是局部变量
成员变量如果没有手动赋初始值的话,系统会自动给成员变量赋其默认值。
5.成员变量赋默认值
数据类型 默认值
----------------------
byte 0
short 0
int 0
long 0L
float 0.0F
double 0.0
boolean false
char \u0000
引用数据类型 null
2.对象
依据定义:类是我们定义的、对 对象 特征总结形成的模板,是个抽象概念。因此我们需要创建实例也就是对象,才能真正的完成工作。
就好比宠物都会吃饭,你说宠物这个标签,标签只是个概念,不会吃饭,会吃饭的是真正的宠物,比如说猫和狗。
对象的定义语法:
new 类名();
但是,对象是存储在堆这个内存空间的,而Java语法规定程序员不能直接对堆内的内容进行访问,所以就诞生了引用,C++中的指针。
引用和对象要区分开。对象在JVM堆当中。引用是保存对象地址的变量。
引用就是存储对象在堆内存中地址的变量,这个变量应该是引用类型的变量。表示如下:
平时为了方便,就把存储对象地址的局部变量叫做对象
Student s1 = new Student();
3.实例变量的访问语法:
对象名.变量名;
相当于对象的变量
示例代码:
package com.powernode.javase.oop01;
public class StudentTest01 {
public static void main(String[] args) {
// 局部变量
int i = 10;
Student s1 = new Student();
System.out.println("姓名:" + s1.name); // null
System.out.println("年龄:" + s1.age); // 0
System.out.println("性别:" + (s1.gender ? "男" : "女"));
// 修改对象的属性(修改变量的值,给变量重新赋值)
s1.name = "张三";
s1.age = 20;
s1.gender = true;
System.out.println("姓名:" + s1.name); // 张三
System.out.println("年龄:" + s1.age); // 20
System.out.println("性别:" + (s1.gender ? "男" : "女")); // 男
// 再创建一个新对象
Student s2 = new Student();
// 访问对象的属性
System.out.println("姓名=" + s2.name); // null
System.out.println("年龄=" + s2.age); // 0
System.out.println("性别=" + (s2.gender ? "男" : "女"));
// 修改对象的属性
s2.name = "李四";
s2.age = 20;
s2.gender = false;
System.out.println("姓名=" + s2.name); // 李四
System.out.println("年龄=" + s2.age); // 20
System.out.println("性别=" + (s2.gender ? "男" : "女")); // 女
}
}
上述代码的内存图表示如下:
4.实例方法的定义与访问
定义:
public 返回值类型 方法名(形式参数列表){
**方法体
}
行为又叫实例方法,不再用static修饰符的原因:static修饰符,代表由类名进行调用,但是对于定义对象的抽象类来说,不能用此语法,因为他是个抽象的概念,不是实例。
实例方法的调用:
对象名.方法名();
5.不可以用类名来调用实例对象和实例方法
1.类是一个抽象的概念,不是一个具体的事物。
2.对象的信息存储在堆内存中,而堆内存不能被程序员直接访问,必须借助存储对象地址的变量来访问,类名不可以。
6.当引用为null时候:
示例代码如下:
package com.powernode.javase.oop03;
/**
* 宠物类
*/
public class Pet {
// 属性:状态
// 名字
String name; // 实例变量
// 出生日期
String birth;
// 性别
char sex;
// 方法:行为动作
// 吃
public void eat(){ // 实例方法
System.out.println("宠物在吃东西");
}
// 跑
public void run(){
System.out.println("宠物在跑步");
}
}
package com.powernode.javase.oop03;
public class PetTest02 {
public static void main(String[] args) {
// 创建宠物对象
Pet dog = new Pet();
// 给属性赋值
dog.name = "小黑";
dog.birth = "2012-10-11";
dog.sex = '雄';
// 读取属性的值
System.out.println("狗狗的名字:" + dog.name);
System.out.println("狗狗的生日:" + dog.birth);
System.out.println("狗狗的性别:" + dog.sex);
//当引用为null
dog = null;
// ==注意:引用一旦为null,表示引用不再指向对象了。但是通过引用访问name属性,**编译可以通过。**==
// 运行时会出现异常:**空指针异常**。NullPointerException。这是一个非常著名的异常。
// 为什么会出现空指针异常?因为运行的时候会找真正的对象,如果对象不存在了,就会出现这个异常。
//System.out.println("狗狗的名字:" + dog.name);
// 会出现空指针异常。
dog.eat();
// 会出现空指针异常。
//dog.run();
}
}
原理如下图所示:
赋值与参数传递的底层逻辑
int i = 10;
int j = i;//j = 10;
赋值的原理:这不代表i和j在局部变量表中共用一个存储10的存储空间。
步骤:
1.先执行赋值符号左边,读取i的值,并将其赋值一份存储在操作数列表中。
2.开辟一个内存空间,空间名字叫j,并放在局部变量列表中。
3.将操作数列表中的10存储在内存空间j中;
参数传递其实就是将实参的值赋值给方法形参变量的过程。
传递的参数类型分两类:基本数据类型 引用数据类型
判断以下程序的输出结果是多少:
package com.powernode.javase.oop04;
public class User {
int age;
}
package com.powernode.javase.oop04;
/**
* 面试题:判断该程序的输出结果
*/
public class ArgsTest01 {
public static void main(String[] args) {
int i = 10;
// 调用add方法的时候,将i传进去,实际上是怎么传的?将i变量中保存值10复制了一份,传给了add方法。
add(i);
System.out.println("main--->" + i); // 10
}
public static void add(int i){ // 方法的形参是局部变量。
i++;
System.out.println("add--->" + i); // 11
}
}
解析如下图:传的只是值,而这两个变量虽然名字一样,但是所属的方法不一样。
package com.powernode.javase.oop04;
public class User {
int age;
}
package com.powernode.javase.oop04;
/**
* 面试题:分析以下程序输出结果
*/
public class ArgsTest02 {
public static void main(String[] args) {
User u = new User();
u.age = 10;
// u是怎么传递过去的。实际上和i原理相同:都是将变量中保存的值传递过去。
// 只不过这里的u变量中保存的值比较特殊,是一个对象的内存地址。
add(u);
System.out.println("main-->" + u.age); // 11
}
public static void add(User u) { // u是一个引用。
u.age++;
System.out.println("add-->" + u.age); // 11
}
}
而这个输出的结果是11,因为参数传递的是值,可是两个变量操作的都是同一个对象,因此会发生该变,解析如下图: