第六章 面向对象编程(基础部分)
目录
一、章节内容概览
二、进入章节内容
(一)类与对象
1. 类与对象引出
2. 类与对象的概述
3. 类与对象的快速入门
4. 对象内存布局【非常重要】
5. 属性/成员变量
(1)属性(也叫成员变量)的概念
(2)属性注意细节
6. 创建对象的访问属性
(1)如何创建对象
(2)如何访问属性
7. 类与对象的内存分配机制【非常重要】
核心逻辑梳理
8. 对象创建过程
9. 对象机制练习
(二)成员方法
(三)成员方法传参机制
(四)重载
(五)可变参数
(六)作用域
(七)构造器
(八)this
一、章节内容概览
-
类与对象
-
成员方法
-
成员方法传参机制
-
重载(overload)
-
可变参数
-
作用域
-
构造器
-
this
二、进入章节内容
(一)类与对象
1. 类与对象引出
看一个养猫猫问题
张老太养了两只猫猫:一只名字叫小白,今年3岁,白色。还有一只叫小花,今年100岁,花色。请编写一个程序,:当用户输入小猫的名字时,就显示该猫的名字,年龄,颜色。如果用户输入的小猫名错误,则显示 张老太没有这只猫猫。
使用现有技术解决 Object01.java
(1)单独的定义变量解决
(2)使用数组解决
代码
public class Object01{//编写一个main方法public static void main(String [] args){/*张老太养了两只猫猫:一只名字叫小白,今年3岁,白色。还有一只叫小花,今年100岁,花色。请编写一个程序,:当用户输入小猫的名字时,就显示该猫的名字,年龄,颜色。如果用户输入的小猫名错误,则显示 张老太没有这只猫猫。我们学习技术的一个套路就是先考虑能不能使用传统的方法来解决,然后我们看使用传统方法来解决的时候会有什么问题?从而引出类与对象。(1)使用单独的变量来解决(2)使用数组来解决*///使用单独的变量来解决//第一只猫猫信息String cat1Name = "小白";int cat1Age = 3;String cat1Color = "白色";//第二只猫猫信息String cat2Name = "小花";int cat2Age = 100;String cat2Color = "花色";//这样解决的缺陷有://第一个,数据多会很麻烦,而且不利于数据的管理,//也就是如果需要增加属性,比如体重就很麻烦//使用数组来解决//第一只猫猫信息String [] cat1 = {"小白", "3", "白色"};//第二只猫猫信息String [] cat2 = {"小花", "100", "花色"};//这样解决的不好之处在于(1)就是数据类型的问题,//比如这里的年龄,本应该是整数,但是在数组//里面是字符串;(2)还有就是只能通过下标来访问,//这就造成了变量名与访问内容不匹配的问题;//(3)还有无法表示猫的行为问题。//由此引出了类与对象来解决这些问题。}
}
现有技术解决的缺点分析:
不利于数据的管理
效率低
===》引出我们的新知识点 类与对象
java设计者 引入 类与对象(OOP),根本原因就是现有的技术不能完美的解决新的需求。
2. 类与对象的概述
(1)前述
在以前的章节中,说过:一个程序就是一个世界,有很多事物。这里的事物在我们的编程中就使用对象来体现。而对像包含两个东西,一个就是属性、一个是行为。
怎么区分这两个东西呢?
用之前的猫猫举例子,比如猫猫就是一个对象,它的的名字、颜色、年龄这些就是它的属性,而如果加上它会叫、会吃东西、会跑,叫、吃、跑这些就是它的行为,可以这样来区分,属性是对象的静态特征,而行为是对象的动态特征。
(2)类与对象的关系示意图
上图说明
注意:从猫类到对象,目前有几种说法:1.创建一个对象 2.实例化一个对象 3.把类实例化 … 以后大家听到这些说法,不要迷糊
当然:上面的猫也可是鱼、狗、人..java最大的特点就是面向对象。
还有一点要特别注意,就是这个类它是一个数据类型,是我们程序员自定义的一个数据类型。相较于之前学的基本数据类型和引用数据类型,这个是我们程序员自己定义的数据类型,而它们是Java内部已经定义好的数据类型。
3. 类与对象的快速入门
使用OOP面向对象解决之前的养猫问题
public class Object01{//编写一个main方法public static void main(String [] args){/*张老太养了两只猫猫:一只名字叫小白,今年3岁,白色。还有一只叫小花,今年100岁,花色。请编写一个程序,:当用户输入小猫的名字时,就显示该猫的名字,年龄,颜色。如果用户输入的小猫名错误,则显示 张老太没有这只猫猫。我们学习技术的一个套路就是先考虑能不能使用传统的方法来解决,然后我们看使用传统方法来解决的时候会有什么问题?从而引出类与对象。(1)使用单独的变量来解决(2)使用数组来解决*///使用单独的变量来解决//第一只猫猫信息//String cat1Name = "小白";//int cat1Age = 3;//String cat1Color = "白色";//第二只猫猫信息//String cat2Name = "小花";//int cat2Age = 100;//String cat2Color = "花色";//这样解决的缺陷有://第一个,数据多会很麻烦,而且不利于数据的管理,//也就是如果需要增加属性,比如体重就很麻烦//使用数组来解决//第一只猫猫信息//String [] cat1 = {"小白", "3", "白色"};//第二只猫猫信息//String [] cat2 = {"小花", "100", "花色"};//这样解决的不好之处在于(1)就是数据类型的问题,//比如这里的年龄,本应该是整数,但是在数组//里面是字符串;(2)还有就是只能通过下标来访问,//这就造成了变量名与访问内容不匹配的问题;//(3)还有无法表示猫的行为问题。//由此引出了类与对象来解决这些问题。//使用OOP面向对象来解决//实例化一只猫【创建一只猫对象】//(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("第一只猫的信息:" + cat1.name + " " + cat1.age + " " + cat1.color);System.out.println("第二只猫的信息:" + cat2.name + " " + cat2.age + " " + cat2.color);}
}//使用面向对象的方式来解决养猫的问题
//定义一个猫类 Cat ----> 自定义数据类型
class Cat{//属性String name;int age;String color;//行为//……
}
编译运行结果:
4. 对象内存布局【非常重要】
对象在内存中的存在形式
Cat cat=new Cat();
cat.name="小白";
cat.age=12;
cat.color="白色";
补充说明【很重要的一点】
对于属性来说,如果是基本数据类型的话,就直接存在堆内存中;如果是引用数据类型的话是存在方法区中,那对于方法来说呢?
5. 属性/成员变量
(1)属性(也叫成员变量)的概念
基本介绍
1. 从概念或叫法上看:成员变量 =属性 = field (字段)(即 成员变量是用来表示属性的,授课中,统一叫 属性)。
案例演示:Car(name,price,color)
class Car {String name;//属性,成员变量,字段fielddouble price;String color;
}
2. 属性是类的一个组成部分,一般是基本数据类型,也可是引用类型(对象,数组).比如我们前面定义猫类 的 int age 就是属'性。
class Car {String name;//属性,成员变量,字段fielddouble price;String color;String [] master; //属性可以是基本数据类型,也可以是引用数据类型(对象,数组)
}
(2)属性注意细节
1)属性的定义语法同变量,但是它多了一个访问修饰符这个东西,示例:访问修饰符 属性类型 属性名;
这里的访问修饰符简单介绍下:就是控制属性的访问范围,有四种访问修饰符,分别是public,proctected,默认,private。具体的会在面向对象编程中级部分详细讲。
2)属性的定义类型可以为任意类型,包含基本类型或引用类型
3)属性如果不赋值,有默认值,规则和数组一致(第五章),如下:
int 0,short 0,byte 0,long 0,float 0.0,double 0.0, char \u0000,boolean false,String null。
案例演示:[Person类] PropertiesDetail.java
public class PropertiesDetail{//编写一个main方法public static void main(String [] args){//p1是对象名(对象引用)//new Person()创建的对象空间(数据)才是真正的对象Person p1 = new Person();//对象的属性默认值,遵循数组规则://int 0,short 0,byte 0,long 0//,float 0.0,double 0.0, char \u0000,//boolean false,String null。System.out.println("\n当前这个人的信息");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;}
编译运行结果:
注明:只是演示了部分数据类型的默认值,其他的一样的。
6. 创建对象的访问属性
(1)如何创建对象
先声明,再创建
Cat cat; //声明对象cat,它还没有开辟空间,在栈区,是一个空值null
cat = new Cat();//当new了之后,就为这个对象开辟了一个空间,有了地址
直接创建
Cat cat = new Cat();
(2)如何访问属性
基本语法
对象名.属性名;
如:
cat.name;
cat.age;
cat.color;
7. 类与对象的内存分配机制【非常重要】
看一个思考题
我们定义一个人类(Persor)(包括 名字,年龄)。
(Object03.java)
我们看看下面一段代码:
Person p1=new Person();
p1.age = 10;
p1.name = "小明";
Person p2 = p1;//把p1赋给了p2,或者说让p2指向p1
System.out.println(p2.age);
请问:p2.age究竟是多少?并画出内存图:
核心逻辑梳理
类加载与对象创建:
- 执行
Person p1 = new Person();
时,首先会在方法区加载Person
类的信息(属性、方法定义)。- 然后在堆内存中为
Person
对象分配空间(图中堆里的0x0011
地址区域),此时对象的属性(age
、name
)会被赋予默认值(age
默认0
,name
默认null
)。- 在栈内存中为引用变量
p1
分配空间,存储堆中对象的地址(图中p1 -> 0x0011
)。属性赋值:
p1.age = 10;
:通过p1
引用找到堆中对象,将age
赋值为10
。p1.name = "小明";
:同样通过p1
引用,将name
赋值为"小明"
,而字符串"小明"
会存储在方法区的常量池中,堆中name
属性存储的是常量池的地址0x0022
。引用传递:
Person p2 = p1;
:是引用传递,在栈中为p2
分配空间,存储和p1
相同的堆对象地址(图中p2 -> 0x0011
),所以p1
和p2
指向同一个堆对象。- 因此
System.out.println(p2.age);
会输出10
,因为p2
指向的对象和p1
是同一个,age
已经被赋值为10
。栈与堆的角色强调:
- 栈内存主要存储局部变量(如
p1
、p2
这些引用),速度快但空间小;堆内存存储对象本身,空间大但速度相对慢。
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指向p1System.out.println(p2.age);}
}class Person{//两个属性int age;String name;
}
编译运行结果验证:
8. 对象创建过程
Java内存的结构分析:
(1)栈:一般存放基本数据类型(局部变量)
(2)堆:存放对象(Cat cat,数组等)
(3)方法区:常量池(常量,比如字符串),类加载信息。
Java创建对象的流程简单分析:
Person p = new Person();
p.name ="jack";
p.age=10
1. 先加载Person类信息(属性和方法信息,只会加载一次)
2. 在堆中分配空间,进行默认初始化(看规则)
3. 把地址赋给 p,p 就指向对象进行指定初始化,比如 p.name ="jack" p.age =10
9. 对象机制练习
//我们看看下面一段代码,会输出什么信息:
Person a = new Person();
a.age = 10;
a.name = "小明":
Person = b;
b = a;
System.out.println(b.name);
b.age = 200;
b = null;
System.out.println(a.age);
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指向p1System.out.println(p2.age);*/Person a = new Person();a.age = 10;a.name = "小明";Person b;b = a;System.out.println(b.name);b.age = 200;b = null;System.out.println(a.age);System.out.println(b.age);}
}class Person{//两个属性int age;String name;
}
编译运行结果:
正确!!!
今天就到这里啦~
明天预告
(二)成员方法
(三)成员方法传参机制
(四)重载
(五)可变参数
(六)作用域
(七)构造器
(八)this
多点赞的话就算我熬夜我也要继续更新哦!!!