面向对象
1.1 面向对象
1.1.1 概念
所谓的面向对象是一种编程思想,通过这种思想可以把生活中的复杂事情变得简单化,从原来的执行者变成了指挥者,面向对象是基于面向过程而言的。
我们经常说的面向对象的编程实现(OOP,Object Oriented Programming)
-
面向过程强调的是过程,例如:
1、打开冰箱 2、把大象放进去 3、关上冰箱 -
面向对象强调结果,例如:
1、 饿了,去平台点餐,这个动作就是面向对象。你没有去市场买菜洗菜做饭。。。只要有app就可以了。
1.1.2 三大特征
- 封装性,把相关的数据封装成一个“类”组件
- 继承性,是子类自动共享父类属性和方法,这是类之间的一种关系
- 多态,增强软件的灵活性和重用性
1.2 类和对象
1.2.1 类
- Java语言最基本单位就是类,类似于类型。
- 类是一类事物的抽象。
- 可以理解为模板或者设计图纸。
1.2.2 对象
每个对象具有三个特点:对象的状态,对象的行为和对象的标识。
- 对象的状态用来描述对象的基本特征。
- 对象的行为用来描述对象的功能。
- 对象的标识是指对象在内存中都有一个唯一的地址用来和其他对象区分开来。
- 类是一类事物的抽象,对象是具体的实现。
1.2.3 类和对象的关系
- 计算机语言是用来描述现实世界事物的。属性+行为
- 那怎么通过java语言描述呢?通过类来描述事物,把事物的属性当做成员变量,把行为当做成员方法。
分析手机事物:
属性:颜色,尺寸,品牌,价格。。。
行为:打电话,发短信,听音乐。。。。
类:手机类,抽取相同的属性和行为
对象:可以按照模板生产很多个手机,比如1号手机对象,包含特有的成员变量和成员方法
1.3 类和对象的创建和使用
1.3.1 练习1:类的创建使用
通过class关键字创建类,通过new关键字创建对象。
package day06;
public class Test1 {
public static void main(String[] args) {
// p是引用对象,持有了对于Person对象的地址值的引用
// 此时的p,含有属性,但都是默认值
Person p = new Person();
// 设置属性值
p.name = "lisi";
p.age = 20;
// 调用方法
p.eat();
p.sleep();
}
}
class Person {
// 属性--成员变量
String name;
int age;
// 行为--方法
void eat() {
System.out.println("吃饭饭");
}
void sleep() {
System.out.println("睡觉觉");
}
}
1.3.2 对象在内存中的存储
Java把内存分成5大区域,我们重点关注栈和堆。
- 一般来讲局部变量存在栈中,方法执行完毕内存就被释放
- 对象(new出来的东西)存在堆中,对象不再被使用时,内存才会被释放
- 每个堆内存的元素都有地址值
- 对象中的属性都是有默认值的
1.3.3 单一对象内存图
- 在栈内存中,创建一个引用变量p,持有对象的地址值
- 在堆内存中,创建Person对象,并且开辟变量的空间,完成初始化
- 给堆内存中的元素,分配一个唯一标志,地址值。交给p去保存。
- p.name=”lisi”;p.age=20;就去堆内存中找唯一的地址值,找到Person对象,并对其属性进行修改赋值。
- p.eat();就去堆内存中找唯一的地址值,找到Person对象,执行Person对象的方法。
1.3.4 练习2:创建多个类
package day06;
public class Test1 {
public static void main(String[] args) {
// p是引用对象,持有了对于Person对象的地址值的引用
// 此时的p,含有属性,但都是默认值
Person p = new Person();
// 设置属性值
p.name = "lisi";
p.age = 20;
// 创建p2
Person p2 = new Person();
p2.name = "zhangsan"
p2.age = 10;
}
}
class Person {
// 属性--成员变量
String name;
int age;
// 行为--方法
void eat() {
System.out.println("吃饭饭");
}
void sleep() {
System.out.println("睡觉觉");
}
}
1.3.5 多对象内存图
- 变量p和变量p1不是一片空间,p1需要开辟新的空间
- Person p1=new Person,这时只要有new,就会新开辟空间在堆内存中存入对象。
1.4 封装
1.4.1 概述
封装是指隐藏对象的属性和实现细节,仅仅对外提供公共的访问方式。
好处:
- 提高安全性
- 提高重用性
1.4.2 private关键字
是一个权限修饰符,用于修饰成员变量和成员函数,被私有化的成员只能在本类中访问。
想要修改只能,对外提供公共的,get和set方法。
1.4.3 练习1:封装学生
先用不同的变量名,不要出现this
package day06;
public class Student {
//String name;
// 把属性隐藏起来
private String name;
// 提供公共的访问方法
// 设置公共的赋值方法
public void setName(String n) {
name = n;
}
// 设置公共的取值方法
public String getName() {
return name;
}
int age;
}
class StDemo {
public static void main(String[] args) {
Student s = new Student();
// 不能访问私有的
// s.name="zhangsan";
// System.out.println(s.name);s
// 利用setXxx()给属性赋值
s.setName("zhangsan");
// 利用getXxx()给属性取值
System.out.println(s.getName());
}
}
1.5 构造方法
1.5.1 概述
构造方法是一种特殊的方法,它是一个与类同名且返回值类型为同名类类型的方法。对象的创建就是通过构造方法来完成,其功能主要是完成对象的创建或者对象的初始化。当类实例化一个对象时会自动调用构造方法。
构造方法和其他方法一样也可以重载。
1.5.2 形式
** 可以无参也可以有参**
修饰符 类名(【参数】){
代码……
}
1.5.3 练习1:构造方法创建对象
package day06;
public class Test2_构造方法 {
String name;
//当存在一个含参的构造方法时,无参构造将不再自动生成...
//public Test2_构造方法(){}
// 含参构造
public Test2_构造方法(String n) {
name = n;
}
void eat() {
System.out.println("Test2_构造方法.eat()");
}
}
class tt {
public static void main(String[] args) {
//注释掉无参的构造也可以运行,说明系统会自动提供一个无参的构造方法
Test2_构造方法 t2 = new Test2_构造方法();
t2.eat();
//t是引用变量,引用的是对象的地址值。
// 根据地址值找到对象,并获取对象的数据
Test2_构造方法 t = new Test2_构造方法("张三");
System.out.println(t.name);
}
}
1.5.4 练习2:构造方法赋值
package day006;
public class Test3_成员变量赋值 {
String name;
int age;
// 赋值方式1:通过含参构造方法赋值
public Test3_成员变量赋值(String name, int age) {
this.name = name;
this.age = age;
}
// 赋值方式2:通过setXxx()方法赋值
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
}
class Test3Demo {
public static void main(String[] args) {
// 赋值方式1:通过无参构造方法赋值
Test3_成员变量赋值 t1 = new Test3_成员变量赋值();
System.out.println(t1.name);
System.out.println(t1.age);
// 赋值方式1.1:通过含参构造方法赋值
Test3_成员变量赋值 t2 = new Test3_成员变量赋值("zhangsan", 30);
System.out.println(t2.name);
System.out.println(t2.age);
// 赋值方式2:通过setXxx()方法赋值
Test3_成员变量赋值 t3 = new Test3_成员变量赋值();
t3.setName("rose");
t3.setAge(25);
System.out.println(t3.name);
System.out.println(t3.age);
}
}
1.6 总结
1.6.1 创建对象的流程
Person p = new Person();//短短这行代码发生了很多事情
1. 把Person.class文件加载进内存
2. 在栈内存中,开辟空间,存放变量p
3. 在堆内存中,开辟空间,存放Person对象
4. 对成员变量进行默认的初始化
5. 对成员变量进行显示初始化
6. 执行构造方法(如果有构造代码块,就先执行构造代码块再执行构造方法)
7. 堆内存完成
8. 把堆内存的地址值赋值给变量p ,p就是一个引用变量,引用了Person对象的地址值
1.6.2 匿名对象
没有名字的对象,是对象的简化表示形式。
使用场景:
1、 当被调用的对象只调用一次时(多次会创建多个对象浪费内存)
Demo d = new Demo();
d.sleep();
d.game();
//这个d就是对象的名字。
也可以写成:
new Demo().show();//创建了一个对象调方法
new Demo().game();//又创建了一个对象调方法