1、初识面向对象

1)面向对象(Object-Oriented Programing,OOP)

2)本质

  • 以类的方式组织代码,以对象的方式组织(封装)数据

    3)三大特性

  • 封装、继承、多态

    4)认识类和对象

  • 认识角度:先有对象后有类,对象是具体的事物,类,是抽象的,是对对象的抽象

  • 代码角度:先有类后有对象,类是对象的模板

    2、方法加固和加深

    1)方法的定义

  • 修饰符

  • 返回类型
  • break和return
  • 方法名
  • 参数列表
  • 异常抛出 ```java package com.oop;

import java.io.IOException;

public class Demo01 { public static void main(String[] args) { / 修饰符 返回值类型 方法名(…){ 方法体 return } / int [] arrays = {1,2,3,4,5}; printArrays(34,3,3,4,5,90,54); }

  1. public static void printArrays(int... arrays){
  2. for (int item:
  3. arrays) {
  4. System.out.print(item + "\t");
  5. }
  6. }
  7. // 异常
  8. public static void readFile(String file) throws IOException{
  9. }

}

  1. <a name="tRVir"></a>
  2. #### 2) 方法的调用
  3. <a name="jsPtD"></a>
  4. #### 2.1)静态方法
  5. - 可以直接通过类名调用方法
  6. - 类创建后立即存在
  7. <a name="jTl3g"></a>
  8. #### 2.2)非静态方法
  9. - 实例化这个类 new,实例调用
  10. - 实例化后才会存在
  11. ```java
  12. //可以调用
  13. public static void a(){
  14. b();
  15. }
  16. public static void b(){
  17. }
  18. -------------------
  19. public static void a(){
  20. b();
  21. }
  22. public static void b(){
  23. }
  24. ------------------
  25. public void a(){
  26. b();
  27. }
  28. public static void b(){
  29. }
  30. // 不可用调用
  31. public static void a(){
  32. b();
  33. }
  34. public void b(){
  35. }
  • 形参和实参
  • 值传递和引用传递 ```java package com.oop;

// 值传递 public class Demo03 { public static void main(String[] args) { int a = 1; System.out.println(“origin a:” + a);//1 Demo03 demo03 = new Demo03(); demo03.change(a);//1 } public void change(int a){ a = 10; } }

#

// 引用传递 package com.oop;

public class Demo04 { public static void main(String[] args) { Person person = new Person(); System.out.println(“orgin name: “ + person.name);//null

  1. Demo04 demo04 = new Demo04();
  2. demo04.change(person);
  3. System.out.println("call after: " + person.name);//秦将
  4. }
  5. public void change(Person person){
  6. person.name = "秦将";
  7. }

}

class Person{ String name; }

  1. - this关键字
  2. <a name="YVOBH"></a>
  3. ### 3、对象的创建分析
  4. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12881754/1622502935805-519794c0-7766-42fa-9fcd-43673013a9ee.png#clientId=ud2b488d4-0c36-4&from=paste&height=301&id=u5d613e06&margin=%5Bobject%20Object%5D&name=image.png&originHeight=602&originWidth=1236&originalType=binary&ratio=1&size=344711&status=done&style=none&taskId=u82f8a28b-ed47-46a8-b328-004ab1d68d5&width=618)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/12881754/1622504151141-6a899539-3c0a-43d9-9071-4dce73c78e4b.png#clientId=ud2b488d4-0c36-4&from=paste&height=114&id=u4edfd6f9&margin=%5Bobject%20Object%5D&name=image.png&originHeight=227&originWidth=798&originalType=binary&ratio=1&size=78160&status=done&style=none&taskId=u2e44ba2c-4800-48b4-8489-800ed3ad207&width=399)
  5. <a name="hUxjP"></a>
  6. #### 1)示例代码
  7. ```java
  8. // Person
  9. package com.oop;
  10. public class Person {
  11. //1、 一个类什么也不用写,也会存在一个构造方法
  12. // 实例化初始值
  13. // 2、使用new关键字,本质在调用构造器
  14. // 有参构造,一旦定义有参函数,无参必须显示定义
  15. String name;
  16. public Person(String name) {
  17. this.name = name;
  18. }
  19. }
  20. // Student
  21. package com.oop;
  22. public class Student {
  23. public static void main(String[] args) {
  24. Person person = new Person("请讲");
  25. System.out.println(person.name);
  26. }
  27. }

2) 创建对象内存分析

image.png

  1. // application
  2. package com.oop;
  3. public class Application {
  4. public static void main(String[] args) {
  5. Pet dog = new Pet();
  6. dog.name = "旺财";
  7. dog.age = 11;
  8. dog.shout();
  9. Pet cat = new Pet();
  10. }
  11. }
  12. //pet
  13. package com.oop;
  14. public class Pet {
  15. public String name;
  16. public int age;
  17. public Pet() {
  18. }
  19. public void shout(){
  20. System.out.println("交了一声");
  21. }
  22. }

3) 总结

image.png
image.png

4、面向对象三大特性

1)封装

image.png

1.1)作用

  • 快捷键 构建构造函数 alt+insert+shfit
  • 提高程序的安全性
  • 隐藏代码的实现细节
  • 统一接口
  • 系统可维护增加 ```java //app package com.oop;

public class Application { public static void main(String[] args) { Pet dog = new Pet(); dog.setAge(300); int age = dog.getAge(); System.out.println(age);

  1. }

} //pet package com.oop;

public class Pet { private String name; private int age;

  1. public String getName() {
  2. return name;
  3. }
  4. public void setName(String name) {
  5. this.name = name;
  6. }
  7. public int getAge() {
  8. return age;
  9. }
  10. public void setAge(int age) {
  11. if (age < 0 || age >130){
  12. this.age = 1;
  13. }else {
  14. this.age = age;
  15. }
  16. }

}

  1. <a name="RcMwy"></a>
  2. #### 2)继承
  3. - **定义**
  4. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12881754/1622906384103-108a8817-c000-477d-8307-47e35e15927e.png#clientId=u1b61bc11-c018-4&from=paste&height=382&id=u515e49fd&margin=%5Bobject%20Object%5D&name=image.png&originHeight=763&originWidth=1576&originalType=binary&ratio=2&size=307664&status=done&style=none&taskId=u2177c11a-20b7-4a14-8f83-b5f09cde6b7&width=788)
  5. - 在java中默认继承object类
  6. - 查看继承关系,快捷键 ctrl + H
  7. ```java
  8. //app
  9. package com.oop;
  10. public class Application {
  11. public static void main(String[] args) {
  12. Student student = new Student();
  13. student.say();
  14. }
  15. }
  16. //person
  17. package com.oop;
  18. public class Person {
  19. //1、 一个类什么也不用写,也会存在一个构造方法
  20. // 实例化初始值
  21. // 2、使用new关键字,本质在调用构造器
  22. // 有参构造,一旦定义有参函数,无参必须显示定义
  23. public Person() {
  24. }
  25. String name;
  26. public Person(String name) {
  27. this.name = name;
  28. }
  29. public void say(){
  30. System.out.println("我开始讲了一句话");
  31. }
  32. }
  33. // student
  34. package com.oop;
  35. public class Student extends Person{
  36. public static void main(String[] args) {
  37. }
  38. }

2.1)super()

  • 特别注意点
    • 调用子类构造器,会默认调用父类构造器,先执行子类然后父类
    • 子类构造器中显示写super().必须放在构造函数代码中的第一行
    • 如果父类是有参,子类要调用父类构造函数,必须显示调用且有参
    • super和this不能同时调用构造方法!
  • VS this
    • 代表的对象不同
      • this 本身调用这个对象
      • super 代表父类对象的引用
    • 前提
      • this 没继承也能使用
      • super只有在继承条件中使用
    • 构造方法
      • this 本类的构造
      • super 父类的构造

image.png

2.2)方法重写

  • 重写是对方法的重写,与属性无关
  • 要求
    • 需要有继承关系
    • 方法名必须相同
    • 参数列表必须相同
    • 修饰符:范围可以扩大 public > protected > default >private
    • 抛出异常:范围可以缩小,不能被扩大 ClassNotFoundException -> Exception
    • 必须都是非静态方法,因为静态方法在类创建后便会存在
  • 为什么要重写
    • 父类的功能,子类不一定需要,或者不一定满足
    • ALT+Insert: Override
  • 代码示例 ```java // Student package com.oop;

public class Student extends Person{ public static void main(String[] args) { }

  1. @Override // 注解
  2. public void say() {
  3. System.out.println("我只是个学生而已");
  4. }
  5. public Student() {
  6. // 隐式调用 super()
  7. this.say();
  8. super.say();
  9. System.out.println("我现在还是个学生");
  10. }

} // Person package com.oop;

public class Person { //1、 一个类什么也不用写,也会存在一个构造方法 // 实例化初始值 // 2、使用new关键字,本质在调用构造器 // 有参构造,一旦定义有参函数,无参必须显示定义 public Person() { System.out.println(“我是你爸爸”); }

  1. String name;
  2. public Person(String name) {
  3. this.name = name;
  4. }
  5. public void say(){
  6. System.out.println("你爸爸开始讲了一句话");
  7. }

} // app package com.oop;

public class Application { public static void main(String[] args) { Student student = new Student(); student.say(); } }

  1. <a name="swFWj"></a>
  2. #### 3)多态
  3. <a name="QtzsD"></a>
  4. #### 3.1)定义
  5. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12881754/1623253750522-6a374171-a95d-4b20-9bf3-7539becf3fef.png#clientId=u5cd4a889-6277-4&from=paste&height=271&id=u0c8ca58b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=541&originWidth=959&originalType=binary&ratio=2&size=254005&status=done&style=none&taskId=u4cf0d55b-89be-4887-9599-faa08773a7d&width=479.5)
  6. <a name="JWDV7"></a>
  7. #### 3.2)多态注意事项
  8. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12881754/1623254560438-062e0a40-d9f5-4539-ba5d-a4ca7c94b80a.png#clientId=u5cd4a889-6277-4&from=paste&height=171&id=ubb674c63&margin=%5Bobject%20Object%5D&name=image.png&originHeight=341&originWidth=1185&originalType=binary&ratio=2&size=156211&status=done&style=none&taskId=u84fb80cf-af9e-4f77-9b5c-91b027b27f4&width=592.5)
  9. - 父类型指向子类,但不能调用子类方法
  10. - 实例可以执行的方法,与左边类型有关
  11. - 重写子类方法,执行子类方法
  12. <a name="l8hoX"></a>
  13. #### 3.3)代码示例
  14. ```java
  15. //student
  16. package com.oop;
  17. public class Student extends Person{
  18. @Override
  19. public void run() {
  20. System.out.println("son");
  21. }
  22. public void read(){
  23. System.out.println("read");
  24. }
  25. }
  26. // person
  27. package com.oop;
  28. public class Person {
  29. public void run(){
  30. System.out.println("run");
  31. }
  32. public void say(){
  33. System.out.println("say");
  34. }
  35. }
  36. //appication
  37. package com.oop;
  38. public class Application {
  39. public static void main(String[] args) {
  40. Student student = new Student();
  41. Person student1 = new Student();// 父类型指向子类,但不能调用子类方法
  42. student.run();// 实例可以执行的方法,与左边类型有关
  43. student1.run();// 重写子类方法,执行子类方法
  44. ((Student)student1).read();
  45. }
  46. }

4)instanceof

  • 编译是否通过取决于 两个类型间是否有直接关系,而非间接关系 ```java package com.oop;

public class Application { public static void main(String[] args) {

  1. //Object > Person > Student
  2. //Object > Person > Teacher
  3. //Object > String
  4. Student student = new Student();
  5. System.out.println(student instanceof Person);//true
  6. System.out.println(student instanceof Object);//true
  7. System.out.println(student instanceof Student);//true
  8. //System.out.println(student instanceof Teacher); 编译报错 非继承关系
  9. //System.out.println(student instanceof String); 编译报错,非继承关系
  10. System.out.println("#####################################");
  11. Person p = new Student();
  12. System.out.println(p instanceof Person);//true
  13. System.out.println(p instanceof Object);//true
  14. System.out.println(p instanceof Student);//true
  15. System.out.println(p instanceof Teacher);//false

// System.out.println(p instanceof String); 编译报错,非继承关系

  1. System.out.println("#####################################");
  2. Object o = new Student();
  3. System.out.println(o instanceof Person);//true
  4. System.out.println(o instanceof Object);//true
  5. System.out.println(o instanceof Student);//true
  6. System.out.println(o instanceof Teacher);//false
  7. System.out.println(o instanceof String); //false
  8. }

}

  1. <a name="Wik1e"></a>
  2. #### 5)类型转化
  3. - 调用结果 以右边类型方法为主
  4. ```java
  5. package com.oop;
  6. public class Application {
  7. public static void main(String[] args) {
  8. // 高类型调用低类型方法 需要强制转换
  9. Person p1 = new Student();
  10. ((Student)p1).read();
  11. // 低类型调用高类型方法 可能会丢失自己的一些方法
  12. Student student = new Student();
  13. Person p2 = student;// son run
  14. //p2.read();//编译报错
  15. p2.run();
  16. }
  17. }

5.1)总结

image.png

6)static 关键字

  • static 变量类名可访问,非关键字类名不可访问
  • 实例都可以访问

    6.1)静态代码、匿名代码、构造方法的执行顺序

  • 注意:静态方法只执行一次 ```java package com.oop;

public class Person { public static int age; public double name;

  1. {
  2. System.out.println("匿名代码块");
  3. }
  4. static {
  5. System.out.println("静态代码块");
  6. }
  7. public Person() {
  8. System.out.println("构造方法");
  9. }
  10. public static void main(String[] args) {

// System.out.println(age); // System.out.println(name); 编译报错,不能调用非静态方法 Person person = new Person(); System.out.println(“################################”); Person person1 = new Person();

  1. }

}

#

静态代码块 匿名代码块 构造方法

#

匿名代码块 构造方法

  1. <a name="CiPqZ"></a>
  2. #### 6.2)导入静态包
  3. ```java
  4. package com.oop;
  5. import static java.lang.Math.random;
  6. import static java.lang.Math.PI;
  7. public class Person {
  8. public static void main(String[] args) {
  9. System.out.println(random());
  10. System.out.println(PI);
  11. }
  12. }

5、抽象类和接口

5.1 定义

image.png

  • 接口可以多继承,插座可以插什么头
  • 思考题?
    • 抽象类不能new对象,那么存在构造器吗? ```java //Student package com.oop.Demo07;

public abstract class Student {

  1. public abstract void doSomething();
  2. public void run(){
  3. System.out.println("Student run!");
  4. }

} //application package com.oop.Demo07;

public class Application extends Student{ @Override public void doSomething() { System.out.println(“该做些什么呢?”); }

  1. public static void main(String[] args) {
  2. Application application = new Application();
  3. application.doSomething();
  4. application.run();
  5. }

}

  1. <a name="TBRxQ"></a>
  2. #### 5.2 接口
  3. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12881754/1623369090788-f9170d70-de22-472b-84ff-987449ec7bd3.png#clientId=ue96d2994-8cfb-4&from=paste&height=217&id=u04ca8cb0&margin=%5Bobject%20Object%5D&name=image.png&originHeight=433&originWidth=1256&originalType=binary&ratio=2&size=469479&status=done&style=none&taskId=uf5c39e9a-b6aa-439b-8760-977f0c402dc&width=628)
  4. - **接口的作用**
  5. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12881754/1623369815426-362483eb-580f-4cbc-845a-7a3b5de959e0.png#clientId=ue96d2994-8cfb-4&from=paste&height=185&id=u1fa45c27&margin=%5Bobject%20Object%5D&name=image.png&originHeight=370&originWidth=851&originalType=binary&ratio=2&size=168950&status=done&style=none&taskId=u5483fb32-23b7-4591-80c0-5ee933b763b&width=425.5)
  6. ```java
  7. // UserService
  8. package com.oop.Demo08;
  9. public interface UserService {
  10. void addUser();
  11. void deleteUser();
  12. void editUser();
  13. void queryUser();
  14. }
  15. // UserImpl
  16. package com.oop.Demo08;
  17. public class UserImpl implements UserService{
  18. @Override
  19. public void addUser() {
  20. System.out.println("添加用户");
  21. }
  22. @Override
  23. public void deleteUser() {
  24. System.out.println("删除用户");
  25. }
  26. @Override
  27. public void editUser() {
  28. System.out.println("编辑用户");
  29. }
  30. @Override
  31. public void queryUser() {
  32. System.out.println("查询用户");
  33. }
  34. }

6、内部类和OOP实战

6.1 内部类

image.png

  • 一个java文件可以有多个class文件,但只能有一个public class类 ```java //成员内部类 package com.oop.Demo09;

public class Outer { private int id = 10; public void out(){ System.out.println(“这是外部类的方法”); }

  1. class Inner{
  2. public void in(){
  3. System.out.println("这是内部类的方法: "+id);
  4. }
  5. }

}

package com.oop.Demo09;

public class Appication { public static void main(String[] args) { Outer outer = new Outer(); // 1.通过外部类实例化内部类 Outer.Inner inner = outer.new Inner(); inner.in(); // 2.访问内部类 私有属性

  1. }

}

//静态内部类 内部类加上static即可

//局部内部类 package com.oop.Demo09;

public class Outer { public void method(){ // 局部内部类 class Inner{ public void in(){ System.out.println(“局部内部类”);

  1. }
  2. }
  3. }

}

class A{

} //匿名内部类

没有名字初始化类,不用将实例保存到变量中

package com.oop.Demo09;

public class Outer { public static void main(String[] args) { new UserService() { @Override public void eat() {

  1. }
  2. }
  3. }

}

interface UserService{ void eat(); } ```