今日内容
- 面向对象概述
- 面向对象内存图
- private、this关键字和封装
- 面向对象之构造方法
- 面向对象三大特征
- 封装
- 继承
- 多态
01. 面向过程和面向对象思想概述
- 什么是面向过程?
- 什么是面向对象?
- 面向对象思想的好处是什么?
总结:
1. 面向过程: 强调的是过程, 自己通过第一步, 第二步.. 一步步的自己去完成对应的需求.
2. 面向对象: 强调的是对象, 通过指挥对象去帮我们完成对应的需求.
3.
1. 面向对象是一种[思想], 更符合我们思考问题的一种习惯. (懒人习惯)
2. 将复杂的问题简单化
3. 将我们从[执行者]的位置, 变成了[指挥者].
结论:
Java中讲究万物皆[对象]
可以通过Java代码, 将现实生活的任意一种事物, 都看作为是一个对象
因为任何一种事物都会具备自己的一份[功能].
02. 面向对象思想特点和举例
总结:
懒人思想, 指挥对象去做某件事情.
买电脑:
面向过程:1. 上网学习各个参数的解释
2. 了解各个品牌的性价比
3. 购买..
面向对象:找一个[懂电脑的人]帮我去买
洗衣服:
锅包肉:
03. 类和对象的概述
- 如何通过java描述现实生活中事物
- 类是由什么组成的?
- 类和对象的关系是什么?
测试类 : 带有main方法的类
类 : 基本类 -> 封装[事物][数据]的一个类.
总结:
1. java中描述现实生活事物, 都是通过类的形式
学生事物
class Student{
}
车事物
class Car{
}
动物事物
class Animal{
}
2. 事物(类) : 属性, 行为
属性 : 一个事物的描述信息
姓名, 年龄, 毕业院校...
行为 : 该事物具体能做的功能
学习
问题: 属性在代码中如何表示?
使用[成员变量]进行表示 : 成员变量跟之前定义变量的格式一样, 只不过位置发生了改变
[类中, 方法外]
// 当前的类是描述学生这个事物, 通过三个成员变量(属性)进行了描述
public class Student {
String name = "张三";
int age = 23;
String school = "传智专修学院";
public void study(){
System.out.println("学生学习");
}
}
public class Car{
// 属性
String pinpai = "奇瑞QQ";
double jiage = 50000;
// 行为
public void run(){
System.out.println("跑");
}
}
问题: 行为在代码中如何表示?
使用的是[成员方法]进行表示 : 成员方法, 跟之前定义方法的格式一样, 只不过去掉了static关键字.
3. 类仅仅是对事物进行了一个描述, 可以将类看做为是一个设计图纸
我们真正需要使用的是具体存在的事物.
类 : 描述
对象 : 具体存在的事物
结论 : 我们需要根据类, 去创建对象.
04. 手机类的定义
- 属性和行为分别用什么表示?
- 又该如何编写?
总结:
1. 成员变量, 成员方法
属性 : 品牌, 价格, 颜色
行为 : 大电话, 发短信
2.
public class Phone {
/*
属性 : 品牌, 价格, 颜色
行为 : 打电话, 发短信
*/
String brand; // 成员变量 : 跟之前定义变量的格式一样, 只不过位置挪到了[类中方法外]
double price;
String color;
// 成员方法 : 跟之前定义的方法格式一样, 只不过去掉了static关键字
public void call(String name){
System.out.println("给" + name + "打电话");
}
public void sendMessage(){
System.out.println("手机群发群信");
}
}
- 成员变量和局部变量的区别:
1. 位置区别:
成员变量 : 类中方法外
局部变量 : 方法中, 或者是方法的声明上(形参)
public static void main(String[] args){
int num = 10; // 方法中
System.out.println(num);
}
public static void method(int num){ // 方法的声明上
System.out.println(num);
}
铺垫: 局部代码块, 局部内部类..
只要是跟局部相关的, 都跟方法有关.
2. 初始化值的区别 :
成员变量 : 有默认初始化值.
局部变量 : 没有默认初始化值, 使用之前必须完成赋值才能使用.
(这仅仅是一部分)
05. 对象的使用
- 如何创建对象?
- 如何调用对象的属性?
- 如何调用对象的行为?
总结:
1. 类名 对象名 = new 类名();
Phone p = new Phone();
2. 对象名.变量名;
p.color = "黑色";
System.out.println(p.color);
3. 对象名.方法名(实际参数);
p.call("张三");
p.sendMessage();
属性: 品牌, 价格, 颜色
行为: 打电话, 发短信
打电话的功能要求加入姓名
例如: 给张三打电话.
5分钟时间自己编写.
06. 一个对象的内存图
07. 方法共用的内存图
- 总结: 在一次程序的执行过程中如果创建了多个对象
- .class文件只加载一次
- 字节码文件只有一份, 所以多个对象, 使用的方法, 就是同一份方法.
- 扩展:
垃圾回收机制
Java语言有完善的垃圾回收机制, 会在不定时的时候对内存中的垃圾[自动]进行清扫
啥是内存中的垃圾?
当堆内存中数据[数组对象]的地址值, 没有任何一个变量记录的时候, 该数据[对象], 就会变成垃圾对象.
main(){
Phone p = new Phone();
p = null;
}
08. 两个对象的内存图(两个引用指向同一个堆内存)
int[] arr = {11,22,33};
int[] arr2 = arr;
Phone p1 = new Phone();
p1.color = "白色";
Phone p2 = p1;
p2.color = "蓝色";
System.out.println(p1.color);
System.out.println(p2.color);
09. 成员变量和局部变量的区别
总结:
A:位置不同
成员变量 : 类中方法外
局部变量 : 方法中, 或者是方法的声明上(形参)
B:初始化值不同
成员变量 : 有默认初始化值
局部变量 : 没有默认初始化值, 使用之前必须完成赋值才能使用.
C:生命周期不同
成员变量 : 随着对象的创建而存在, 随着对象的消失而消失
局部变量 : 随着方法的调用而存在, 随着方法的弹栈而消失
D:内存位置不同
成员变量 : 堆内存
成员变量所属于对象, 所以在堆内存
局部变量 : 栈内存
局部变量所属于方法, 所以在栈内存
E:作用域不同(编写代码)
成员变量 : 在整个类当中.
局部变量 : 仅在它所在的大括号中有效
main(){
for(int i = 1; i <= 10; i++){
System.out.println(i);
}
System.out.println(i); // 出现编译错误.
}
10. private关键字的概述和特点
- private权限修饰符可以修饰什么?
- 被其修饰的(成员)有什么特点?
总结:
1. 可以用来修饰[成员]
成员变量
成员方法
2. 只能在本类中进行访问
class Student {
// 原因: 就是为了防止接受到一些错误的数据.
private int age;
// 提供: age的公共访问方式
// 1. [设置的渠道]
public void setAge(int a){
if(a >= 0 && a <= 200){
age = a;
}else{
System.out.println("您的数据有误");
}
}
// 2. [获取的渠道]
public int getAge(){
return age;
}
}
11. private修饰后的[标准类]代码
public class TestPerson {
public static void main(String[] args) {
Person p = new Person();
p.setName("张三");
p.setAge(23);
System.out.println(p.getName() + "..." + p.getAge());
}
}
class Person{
private String name;
private int age;
public void setName(String n){
name = n;
}
public String getName(){
return name;
}
public void setAge(int a){
age = a;
}
public int getAge(){
return age;
}
}
问题: setXxx和getXxx方法一定要成对儿出现吗?
setScore() getScore();
总结:
不一定, 需要根据具体的业务去组织.
12. this关键字的概述和使用
- 什么是this关键字
- this关键字的作用是什么?
总结:
1. this: 代表当前对象的引用, 谁来调用我, 我就代表谁
对象的引用 : 对象的地址值.
2. 用来区分局部变量, 和成员变量的重名问题
3. 结论 : this.用来调用本类的成员.
public class Person{
private String name;
public String getName(){
return name; // 实际上的代码 : return this.name;
}
}
(6分钟)
定义一个学生类
属性:姓名和年龄
生成对应的getter/setter方法
使用this关键字区分局部和成员变量
新建一个测试类测试学生类
13. 封装的概述和好处
- 概述下什么是封装?
- 封装的好处又是什么?
总结:
1. 隐藏实现细节, 仅对外暴露公共的访问方式.
常见的封装 : 私有成员变量, 对外提供公共的setXxx和getXxx方法.
注意: 私有仅仅是封装的一种体现形式, 不能说封装就是私有.
封装是一个大的思想概念 :
1. 将一段代码, 抽取到方法中, 这就是对代码的一个封装.
作为调用者, 我不需要关注方法内部的实现原理, 我只需要关注怎样调用
2. 将数据抽取到一个类当中, 这是对数据的一种封装.
需求: 存储学生信息(姓名, 年龄, 成绩, 学校)
class Student{
// 姓名, 年龄, 成绩, 学校
}
2.
1. 提高了代码的安全性 -> age : -23
2. 提高了代码的复用性 -> 将一段代码封装到一个方法中, 对方法进行重复调用
------------------------------
封装的弊端 :
1. 封装本身没什么弊端, 如果有弊端存在, 只能说明该程序员写的代码太烂
2. 调用成员变量的时候, 稍微麻烦了一点.
不能直接对象名.属性名调用, 需要调用setXxx和getXxx方法.
14. 构造方法的概述和使用
- 什么是构造方法?
- 构造方法的格式为?
- 构造方法可以有return语句吗?
总结:
1. 构建, 或者说是创造一个对象时候, 调用的方法
创建对象时候, 执行的方法.
如果一个类, 没有构造方法, 将无法创建对象
Person p = new Person();
2.
1. 方法名与类名相同, 大小写也要一致
2. 没有返回值类型, 连void都没有
3. 没有具体的返回值
class Person{
public Person(){
System.out.println("我是空参构造方法");
return;
}
}
3. 构造方法可以写return语句, 但是return不能跟具体的返回值, 只能用于结束方法.
问题: 构造方法在什么时候被调用? 能不能手动调用?
创建对象的时候, 会由系统自动调用构造方法, 每创建一次对象, 就会执行一次构造方法.
Person p1 = new Person();
p1.Person(); // 编译错误
结论 : 构造方法不能手动调用, 只能是在创建对象的时候, 由系统自动调用.
问题: 构造方法的作用是什么?
需要结构构造方法的执行时机进行思考
构造方法是在创建对象的时候, 就会执行的方法.
我们希望构造方法在执行的时候, 帮我们干点活.
为成员变量进行赋值
总结 : 用于给对象中的数据[属性]进行初始化的.
15. 构造方法的注意事项
- 构造方法注意事项?
- 构造方法能够重载吗?
- 给成员变量的两种初始化方式有什么区别?
总结:
1. 如果一个类当中没有编写任何构造方法, 系统将会提供一个默认的空参构造方法, 保证可以创建对象
class Person{
// 空参构造方法
// public Person(){}
}
Person p = new Person(); // 这句话不会出现编译错误, 因为在使用Person类的默认空参构造
但是如果手动编写了构造方法, 系统将不会再提供那个默认的空参构造方法了
class Person{
String name;
public Person(String name){
this.name = name;
}
}
Person p = new Person(); // 这句话就会产生编译错误, 因为手动给出了有参构造, 系统就不会提供那个默认的空参构造方法了
建议: 今后编写代码的时候, 空参有参构造, 都手动给出
2. 构造方法也是方法, 可以进行重载
3.
两种初始化方式分别为:
1. 有参构造初始化
2. setXxx初始化
这两种方式一般都是配合使用的.
一般都会通过有参构造进行[初始化], 随后通过setXxx方法[修改]属性值.
Student s = new Student("张三",23);
s.setName("李四");
System.out.println(s.getName());
16. 标准的学生类代码编写和测试
1. 私有成员变量
2. 提供setXxx和getXxx方法
3. 提供空参有参构造