Loading... # 一、面向对象 ## 1.1 面向过程 ``` 回想我们之前写过的代码,我们要做一件事情的时候,会先分析这件事情怎么去做,然后通过代码一步一步去实现。而这一步步的实现是需要我们全程参与,这些过程通过互相之间的调用和协调来完成我们的需求,这种处理问题的方式被我们称为面向过程 代表性的语言:C语言 ``` ## 1.2 面向对象 ``` 但是随着需求的增加,代码的内容肯定会也相应的增加,这就代码的复杂性。 回想之前我们学过的数组,遍历一个数组的时候,我们可以写一个for循环来解决。但是要遍历10个数组的时候,怎么办呢?我们使用了方法来进行改进。对一个数组我们有了多种操作:数组的遍历、数组的求最值、数组的反转等,这些我们都用方法进行改进。我们知道所有的方法都是定义在类中,所以我们可以将这些对数组的操作都放在一个类中,以后想要对数组进行操作的时候,只要通过类的具体的实例来调用这些方法完成相应的功能即可。这种处理问题的方式被我们称为面向对象。 代表性的语言:Java ``` 例子 ``` 做饭: 面向过程:买菜-择菜-洗菜-切菜-炒菜-装盘 面向对象:服务员(点菜)-厨师(炒菜)-服务员(上菜) 买电脑: 面向过程:分析需求-根据需求找相应配置的电脑-去电脑城-购买到手 面向对象:将需求提供给懂电脑的对象-这个对象去买电脑-购买到手 ``` ## 1.3 面向过程和面向对象的关系 ``` 面向对象是基于面向过程的 ``` ## 1.4 面向对象的好处 ``` 将复杂的问题简单化 更符合人类的思维习惯 将我们从问题的执行者,变成了指挥者 ``` ## 1.5 面向对象的特征 ``` 封装 继承 多态 ``` # 二、类与对象 现实世界中是如何描述一个事物的 ``` 属性:姓名、年龄 一般都是名词 行为:唱歌、跳舞、闪电鞭 一般都是动词 ``` Java就是为了解决现实世界中的问题而存在的,Java中是如何描述一个事物的呢? Java中最基本的单位是类,所以我们可以使用类来对现实世界中的事物进行描述 ``` 成员变量: 相当于现实中的属性 成员方法: 相当于现实中的行为 成员变量:与之前讲过的局部变量差不多,只不过成员变量是声明在类中方法外的,并且成员变量不用进行初始化就能使用 成员方法:与之前我们使用的方法差不多,只不过这个地方就先不用static了,而是直接被public修饰 ``` ## 2.1 什么是对象? > 对象是类的一个具体的表现 ``` 比如: 类: 汽车 对象: 五菱宏光、迈巴赫、宝马 类: 学生 对象: 郭泰 ``` ``` 注意事项:一个java文件中可以放多个类,但是只能有一个被public修饰 ``` #### 2.2 案例:学生类 ```java class Student { //成员变量(相当于属性):姓名、年龄 //姓名 String name; //年龄 int age; //成员方法(相当于行为):吃饭、睡觉、学习 //吃饭 public void eat() { System.out.println("吃饭"); } //睡觉 public void sleep() { System.out.println("睡觉"); } //学习 public void study(String ss) { System.out.println(ss + "学习"); } } ``` # 三、使用类中的成员 ## 3.1 创建对象 ``` 格式: 数据类型 对象名 = new 数据类型(...); 格式的解释: 数据类型:只能是引用数据类型,比如说之前见过的Scanner,也可以是现在创建的Student类 对象名: 实际上是一个引用,用来存储对象的地址 =:将在堆上new出来的对象的地址赋值给对象名(引用) new:关键字new,用来在堆上开辟空间 数据类型:同上 (...):是一个方法(实际上是一个构造方法),有参就传参,无参就不传 ``` ## 3.2 使用成员变量 ``` 对象名.成员变量名; ``` ## 3.3 使用成员方法 ``` 对象名.成员方法名(...); 注意: ...的意思是 如果有参就传参,如果无参就留空 ``` ```java public class Demo2 { public static void main(String[] args) { //1. 数据类型 对象名 = new 数据类型(...); Student s = new Student(); //2. 使用成员变量 对象名.成员变量名; s.name = "马保国"; s.age = 69; System.out.println(s.name); System.out.println(s.age); //3. 使用成员方法 对象名.成员方法名(...); s.eat(); s.sleep(); s.study("马保国的弟子"); } } ``` # 四、对象的内存图 ## 4.1 两个对象的内存图 ```java /* * 学生类 */ public class Student { //成员变量:姓名、年龄 String name; int age; //成员方法:吃饭、睡觉 public void eat() { System.out.println("吃饭"); } public void sleep() { System.out.println("Zzzzz"); } } /* * 测试类 */ public class Demo { public static void main(String[] args) { //1. 创建对象 Student s = new Student(); //2. 使用对象调用成员变量 System.out.println(s.name + "---" + s.age); //3. 给成员变量赋值 s.name = "马云"; s.age = 56; s.eat(); System.out.println(s.name + "---" + s.age); System.out.println("--------------------"); //2. 创建第二个对象 Student s2 = new Student(); System.out.println(s2.name + "---" + s2.age); s2.eat(); s2.name = "马老师"; s2.age = 55; System.out.println(s2.name + "---" + s2.age); } } ``` ![image-20201123135523592.png][1] ## 4.2两个引用指向同一个对象 ```java /* * 学生类 */ public class Student { //成员变量:姓名、年龄 String name; int age; //成员方法:吃饭、睡觉 public void eat() { System.out.println("没有鸡腿"); } public void sleep() { System.out.println("没有睡好"); } } public class Demo2 { public static void main(String[] args) { Student s = new Student(); System.out.println(s.name + "---" + s.age); s.name = "马云"; s.age = 56; s.sleep(); System.out.println(s.name + "---" + s.age); System.out.println("------------"); //两个引用指向同一个对象 Student s2 = s; System.out.println(s2.name + "---" + s2.age); s2.name = "马老师"; s2.age = 55; s2.sleep(); System.out.println(s2.name + "---" + s2.age); } } ``` ## 4.3 对象的创建过程 ``` 1. 将要执行的类的字节码加载到方法区中 2. 在栈中声明一个类的引用,这个引用是用来存储真正对象的地址的 3. 在堆上用new开辟了一块空间,产生了一个指向该空间的地址 4. 堆中对象的地址被赋值给了栈中的引用 ``` ## 4.4 成员变量和局部变量的区别 ``` 局部变量:声明在方法上或者方法内部 成员变量:声明在类中方法外 声明位置的不同: 局部变量:声明在方法上或者方法内部 成员变量:声明在类中方法外 内存中的位置不同: 局部变量:栈上 成员变量:堆上 生命周期的不同: 局部变量:随着方法的调用而存在,随着方法的调用结束而消失 成员变量:随着对象的创建而存在,随着对象的回收而消失 初始化值的不同: 局部变量:必须要进行初始化 成员变量:不用进行初始化,因为它有默认的初始化值 整数类型: 0 小数类型: 0.0 布尔类型: false 字符类型: '\u0000' 引用数据类型: null ``` # 五、匿名对象 > 没有名字的对象。 比如:new Student() ## 5.1 使用场景 ``` 1. 对象只使用一次的时候 2. 把匿名对象当做参数来使用 ``` ```java public class Demo3 { public static void main(String[] args) { // Student s = new Student(); // // //1. 下面要调用sleep、eat方法及name变量,有3次,这个时候使用引用s代替更好 // s.sleep(); // s.eat(); // // s.name = "李斯特"; //2. 如果只调用sleep()方法,用这么一次的话,那么可以使用匿名对象。 // new Student().sleep(); } } ``` ```java public class Demo4 { public static void main(String[] args) { //方式一:先创建好一个对象,然后将对象传递给test方法 // Student s = new Student(); // test(s); //方式二:使用匿名对象 test(new Student()); } public static void test(Student s) { //要的是一个类类型,实际上需要的是该类的对象 System.out.println(s.name + "---" + s.age); } } ``` ## 5.2 注意事项 ``` 如果使用匿名对象给类中的成员赋值,那么再去使用匿名对象去访问该成员的时候,并不能取到赋的值(因为这是两个不同的对象) ``` ```java public class Demo5 { public static void main(String[] args) { /* * 每new一下,都会创建一个新的对象 * * 下面使用匿名对象的过程中,new了4次,也就说创建了4个对象 * * 每个对象的成员变量的值不是共享的,是自己独有的 */ new Student().name = "张三"; new Student().age = 56; System.out.println(new Student().name + "---" + new Student().age); } } ``` # 六、封装 > 隐藏了事物的属性及具体的实现细节,而对外提供公共的访问方式 ## 6.2 好处 ``` 1. 提高了代码的安全性 2. 提高了代码的复用性 ``` ## 6.3 原则 ``` 1. 隐藏事物的属性 2. 隐藏事物的实现细节 3. 对外提供公共的访问方式 ``` ```java /* * 我们发现下面的代码出现了逻辑上的错误,因为年龄可以设置为非法数据 -50, * * 如何处理呢? * 1. 要想对年龄age 进行范围设置,肯定要需要 分支结构来进行判断 * 2. 分支结构都是放在方法中的,那么就定义一个方法来进行年龄的判断 * * 方法放在那里呢? * 1. 方法肯定是要写在类中的,但是应该哪个类里面 * 2. 测试类中肯定是不行,因为测试类中主要是用来进行代码测试,这种逻辑性的判断尽量不要放在测试类中 * 3. 所以只能放在学生类中 * * 解决方法: * 1. 在学生类Student中新建一个方法用来判断年龄是否合理 * * 又发现了一个问题,写好的方法,别人不使用。所以我们要强制使用户使用我们这个方法,而不能直接访问到成员变量 * * Java中隐藏一个成员变量,以使这个成员变量只能本类中被访问,出了本类就不能再被访问到了,这个关键字是private */ /* * 学生类 */ class Student { //成员变量:姓名、年龄 String name; private int age; //成员方法:吃饭、睡觉 public void eat() { System.out.println("吃饭"); } public void sleep() { System.out.println("睡觉"); } //判断年龄是否合理,如果合理就设置 public void setAge(int a) { if(a >= 0 && a <= 130) { age = a; }else { System.out.println("您输入的年龄有误!"); } } //定义一个方法,用来展示年龄和姓名 public void show() { System.out.println(name + "---" + age); } } /* * 测试类 */ public class Demo { public static void main(String[] args) { //1. 创建对象 Student s = new Student(); //2. 使用对象调用成员变量 s.name = "张三"; // s.age = -50; s.setAge(-50); s.show(); // System.out.println(s.name + "===" + s.age); } } ``` # 七、private关键字 > private可以修饰成员变量、成员方法,被修饰的成员只能在本类中被访问 ``` 被private修饰的成员只能在本类中被访问,外界访问不了,但是我们可以通过在本类中可以设置一个可以被外界访问的方法(这个本类的方法中,访问本类的私有成员),来间接的访问本类私有的成员 ``` ```java class Car { private String name; //被私有了,只能在本类中被访问 int age; private void drinkOil() { //被私有了,只能在本类中被访问 System.out.println("喝油"); } public void show() { drinkOil(); //访问本类的喝油方法 System.out.println(name + "---" + age); } } public class PrivateDemo { public static void main(String[] args) { Car c = new Car(); c.show(); //通过访问show方法,间接的访问Car类中私有的成员变量name及私有的成员方法drinkOil方法 } } ``` # 八、getter和setter方法 > 因为成员变量已经被private修饰了,只能在本类中被访问了,外界访问不了。为了让外界访问到,我们可以设置一个对外提供公共的方法来进行设置和获取,这些方法一般被我们声明为getXxx和setXxx方法。 > > 其中:setXxx用来设置成员变量的值 getXxx用来获取成员变量的值。 Xxx是成员变量名,注意第一个X大写 ```java class Student { //成员变量 private String name; private int age; //getXxx和setXxx方法 public void setName(String n) { name = n; } public String getName() { return name; } public void setAge(int a) { age = a; } public int getAge() { return age; } //成员方法 public void eat() { System.out.println("吃饭"); } public void sleep() { System.out.println("睡觉"); } //展示成员变量的方法 public void show() { System.out.println(name + "---" + age); } } public class Demo { public static void main(String[] args) { //1. 创建对象 Student s = new Student(); //2. 通过setXxx方法给成员变量赋值 s.setName("张三"); s.setAge(60); //3. 方式一:通过getXxx方法获取成员变量的值 System.out.println(s.getName() + "---" + s.getAge()); //4. 方式二:通过自定义的show方法来获取成员变量的值 s.show(); } } ``` # 九、this关键字 > 哪个对象访问了方法,那么方法中的this就代表哪个对象 ```java class Student { //成员变量 private String name; private int age; //getXxx和setXxx方法 public void setName(String name) { /* * 下方的两个name都是局部变量的name,是同一个,这个name变量会在方法调用结束之后被销毁 * * 变量的访问顺序: * 1. 会先访问局部变量 * 2. 如果局部变量没有,会去成员位置去找 * 3. 如果成员位置没有,那就报错 * * 我们知道 对象名.变量 就可以访问成员位置的变量了 */ this.name = name; } public String getName() { return name; } public void setAge(int age) { this.age = age; } public int getAge() { return age; } //成员方法 public void eat() { System.out.println("吃饭"); } public void sleep() { System.out.println("睡觉"); } //展示成员变量的方法 public void show() { System.out.println(name + "---" + age); } } public class Demo { public static void main(String[] args) { Student s = new Student(); s.setName("张三"); s.setAge(50); System.out.println(s.getName() + "---" + s.getAge()); Student s2 = new Student(); s2.setName("李四"); s2.setAge(66); System.out.println(s2.getName() + "---" + s2.getAge()); } } ``` [1]: https://www.zunmx.top/usr/uploads/2021/04/1316724005.png © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏