一、面向对象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 案例：学生类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 使用成员方法对象名.成员方法名(...); 注意： ...的意思是 如果有参就传参，如果无参就留空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 两个对象的内存图/* * 学生类 */ 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); } }4.2两个引用指向同一个对象/* * 学生类 */ 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. 把匿名对象当做参数来使用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(); } }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 注意事项如果使用匿名对象给类中的成员赋值，那么再去使用匿名对象去访问该成员的时候，并不能取到赋的值（因为这是两个不同的对象）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. 对外提供公共的访问方式/* * 我们发现下面的代码出现了逻辑上的错误，因为年龄可以设置为非法数据 -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修饰的成员只能在本类中被访问，外界访问不了，但是我们可以通过在本类中可以设置一个可以被外界访问的方法（这个本类的方法中，访问本类的私有成员），来间接的访问本类私有的成员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大写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就代表哪个对象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()); } }