模块七 面向对象
第一章 类和对象
1. 面向对象的介绍
1. 面向过程:自己的事情自己干,代表:C语言 洗衣服:每一步自己要亲历亲为,-> 找盆,放水,找搓衣板,搓搓搓 2. 面向对象:自己的事情别人帮忙去干,代表:Java语言 洗衣服:自己的事情别人干 -> 全自动洗衣机 3. 为啥要用面向对象思想编程:懒 很多功能别人都给我们实现好了,我们只需要直接拿过来使用即可,简化了我们自己的编写过程,减少了我们的代码量 4. 什么时候使用面向对象思想编程: 调用别人的功能时 /*在一个类中,想使用别的类中的成员时,就使用面向对象思想编程*/ 至于我们使用的功能,人家怎么实现的,我们只需要知道怎么使用即可 5. 怎么使用面向对象思想编程: a. new ,new完点呀 -> 点代表的是调用 b. 特殊:如果调用的成员带 static 关键字,我们不需要new,我们直接类名点即可
代码实现
import java.util.Arrays; import java.util.Random; import java.util.Scanner; /** * * 在一个类中,想使用别的类中的成员时,就使用面向对象思想编程 * */ public class Demo01Object { public static void main(String[] args){ /* 我们想在Demo01Object类中使用Scanner类中的next方法实现录入字符串 那么我们就需要使用面向对象思想编程 对象:Scanner -> new出来的 对象实现好的功能:next() 我们只需要知道找来Scanner这个对象,就可以调用这个对象中实现好的next方法 至于next方法怎么实现的,我们不需要关心 * */ Scanner sc = new Scanner(System.in); //new 的过程就是找对象的过程 int i = sc.nextInt(); //nextInt前不带static 所以不能直接类名点 String data = sc.next(); System.out.println("data = " + data); System.out.println("================================="); /* * 我们想在Demo01Object类中使用Random类中的nextTnt方法实现随机整数 * 那么我们就需要使用面向对象思想编程 * * 对象:Random -> new 出来的 * 对象实现好的功能:nextInt() * * 我们只需要知道找来Random这个对象,就可以调用Random中的nextInt方法 * 至于nextInt怎么实现的,我们不需要关心 * */ Random rd = new Random(); int i1 = rd.nextInt(); System.out.println("i1 = " + i1); System.out.println("================================="); int[] arr = {1,2,3,4}; System.out.print("["); // for (int i2 = 0; i2 <= arr.length-1; i2++) { // if(i2 == arr.length-1){ // System.out.print(arr[i2] + "]"); // } else{ // System.out.print(arr[i2] + ","); // } // } System.out.println(Arrays.toString(arr));//特殊: 如果调用的成员带 static 关键字,我们不需要new,我们直接类名点即可 /* toString 前面带 static * * Arrays就是我们找来的对象 * toString就是此对象中实现好的功能 * 我们只需要调用,怎么实现我们不关心 * */ } }
2 .对象
1. 概述:类是一类事物的抽象表现形式 ,对象是一类事物的具体实现 2. 使用: a. 导包:import 包名.类名 如果两个类在同一个包下,想要使用对方的成员不需要导包。 如果两个类不在同一个包下,想要使用对方的成员需要导包。 特殊:java.lang -> 使用lang包下的类不需要导包 ->String 友情提示:在学四种权限修饰符之前,尽量让两个类在同一个包下 b. 创建对象 -> /*想要使用哪个类中的成员,就new哪个类的对象*/ 类名 对象名 = new 类名() -> Person ps = new Person(); c. 调用对象(成员变量,成员方法) -> /*想要使用哪个类中的成员,就用哪个类的对象去 点哪个成员*/ 对象名.成员变量名 = 值 对象名.方法名() -> 调用的是无参无返回值方法 对象名.方法名(实参) -> 调用的是有参无返回值方法 数据类型 变量名 = 对象名.方法名() -> 调用的是无参无返回值方法 数据类型 变量名 = 对象名.方法名(实参) -> 调用的是有参有返回值方法
代码实现
public class Demo01Person { public static void main(String[] args) { Person p = new Person(); System.out.println(p.age); System.out.println(p.name); p.name = "张三"; p.age = 26; System.out.println(p.age); System.out.println(p.name); p.eat(); p.drink(); Animal animal = new Animal(); Phone phone = new hone(); } }
3. 练习
需求:用代码去描述一个手机类,在测试类中为手机类中的属性赋值,并且调用手机类中的功能。 public class Demo02Phone { public static void main(String[] args) { Phone phone = new Phone(); phone.brand = "小米"; phone.color = "黑色"; phone.price = 3500; System.out.println("phone.brand = " + phone.brand); System.out.println("phone.color = " + phone.color); System.out.println("phone.price = " + phone.price); phone.call("金莲"); String message = phone.message(); System.out.println("message = " + message); System.out.println("phone.message() = " + phone.message()); } } ------------------------------------------------------------------ public class Phone { //属性 String brand; String color; int price; //行为 public void call(String name){ System.out.println("给" + name + "打电话"); } public String message(){ return "给金莲发短信"; } }
第二章 匿名对象
1. int i = 10; a. int : 是数据类型 b. i: 变量名 c. 等号右边的10:真正的数据 2. Person p = new Person(); a. 等号左边的Person :对象的类型,Person类型 好比是int b. p = 对象名 c. 等号右边的new Person(): 真正的数据,是一个Person对象,将这个对象真正创建出来了 ------------------------------------------------------------ 3. 匿名对象:没有名字的对象,没有等号左边的部分,只有等号右边的部分(对象) 4. 匿名对象的使用: new 对象().成员 例如:new Person().eat(); 5. 注意: a. 如果我们只想单纯的调用一个方法,让方法执行,我们可以考虑使用匿名对象 b. 如果涉及到/**赋值,不要使用匿名对象*/
public class Person { String name; public void eat(){ System.out.println("人要吃饭"); } } ------------------------------------------------------------- public class Demo01Person { public static void main(String[] args) { //老方法 Person p = new Person(); //对象名p 接收 new Person()这个对象 p.name = "金莲"; System.out.println(p.name); p.eat(); System.out.println("===========匿名对象=================="); //调用匿名对象方法 new Person().eat(); new Person().name = "大郎"; System.out.println(new Person().name);//null 而不是大郎,因为输出时候重新new了一个新的Person对象,不是以前的Person对象,新对象没有被赋值,所以涉及到赋值时候 不要使用匿名对象。 } }
第三章 对象的内存解析
1. 一个对象的内存图
2. 两个对象的内存图
new 一次就在堆中开辟一个空间,有一个地址值 new 两次就在堆中开辟两个不同的空间,分别是两个不同的地址值 所以修改两个对象的信息,互不影响
phone1 和 phone2 都是新new出来的对象,所以在堆内存中开辟了两个不同的空间,修改自己空间中的数据不回影响其它空间中的数据。
3. 两个对象指向同一个空间内存图
phone2 是phone1 给的,phone1在内存中保存的是地址值,所以此时phone2和phone1地址值一样,操作同一片空间中的数据,所以修改一个对象的数据会影响另外一个对象
第四章 成员变量和局部变量的区别
1. 定义位置不同(重点) a. 成员变量:类中方法外 b. 局部变量:类中方法中或者参数位置 2. 初始化值不同(重点) a. 成员变量:有默认值,不用手动赋值,就可以直接使用 b. 局部变量:没有默认值,需要先手动赋值后再使用。 3. 作用范围不同(重点) a. 成员变量:作用于整个类 b. 局部变量:之作用于自己所在的方法中,其它方法使用不了。 4. 内存位置不同(了解) a. 成员变量:在堆中,跟着对象走 b. 局部变量:在栈中,跟着方法走 5. 生命周期不同(了解) a. 成员变量:随着对象的创建而产生,随着对象的消失而消失 b. 局部变量:随着方法的调用而产生,随着方法的调用完毕而消失。
public class Person { String name;// 成员变量 public void eat(){ int i = 10;//局部变量 System.out.println(name);//name是成员Person类的变量,有默认值,可以直接使用。 } public void drink(){ int j;//局部变量 // System.out.println(j);//局部变量没有默认值,需要先赋值再使用。 // System.out.println(i);//i是eat()的局部变量 } }
第五章 练习
需求:定义一个类,MyDate,属性有year,month day 再定义一个Citizen(公民类),属性有name(String类型),birthday(MyDate类型) idCard(String),为这三个属性赋值,然后将值取出来。
//创建一个类,类名为MyDate package com.atguigu.e_object; public class MyDate{ int year; int month; int day; }
//创建一个类,类名为Citizen package com.atguigu.e_object; public class Citizen{ String name; String idCard; MyDate birthday;//自定义类型,是引用数据类型。默认值为null }
// 创建一个类,类名为Test01 package com.atguigu.e_object; public class Test01{ public static void main(String[] args){ //要为Citizen类中的属性赋值,则是属性之间的方法,访问哪个类要new哪个类的对象 Citizen citizen = new Citizen(); citizen.name = "小王"; citizen.idCard = "142229"; //citizen.birthday.year = 1999;//空指针异常 /* 因为birthday此时没有被赋值,即是null.year 是空指针 birthday的数据类型为MyDate,是自定义数据类型(引用数据类型) 引用数据类型(除String之外)要操作需要先赋值:new对象赋值 */ //通过new对象给birthday赋值 citizen.birthday = new MyDate(); citizen.birthday.year = 1999;//链式调用 citizen.birthday.month = 10; citizen.birthday.day = 12; System.out.println(citizen.name); System.out.println(citizen.idCard); System.out.println(citizen.birthday.year+ ","+ citizen.birthday.month+ "," +citizen.birthday.day); } }
给引用数据类型赋值,需要new对象(String比较特殊,可以直接=赋值)