面向对象

一、对象

1.1 对象的概念

在程序员世界中,万物皆为对象。

1.2 面向对象

面向过程:采用过程(步骤的方式)来解决问题。

面向对象:在解决问题过程中,考虑有哪些对象参与,再思考这些对象在当前问题中有哪些需要用到特征和行为,根据这些特征和行为进行现实中的模拟,得到最终的结果。

面向接口:在开发过程中,由于分工协作,需要将自己的模块提供相应的接口,其他模块在开发时,应该根据接口来进行相应的开发。

面向服务:在非常复杂的企业级的项目中,会将各个功能封装相应的服务,提供给其他(外部)的调用者调用,叫做面向服务的编程。

将大象放入冰箱。

  • 面向过程的解决方案:
    第一步:打开冰箱
    第二步:把大象塞到冰箱中
    第三步:关上冰箱
    需要宏观的考虑每一步的处理,以及对应的解决方案,针对于简单的问题的解决可以使用此方式。

  • 面向对象的解决方案:
    参与的对象:
    冰箱:特征:容积、入口
    大象:特征:大小
    出力者:行为:放
    针对于复杂的问题,可以进行合理分工,可以模拟现实中的细节,主要要来解决企业中的复杂业务处理流程。

1.3 对象的特点

对象分为特征和行为两部分。

特征:又叫属性,一般是名词。对象有(具备)什么

行为:也叫方法,一般是动词。对象能做什么

1.4 现实对象和程序中对象

现实生活中的对象具备有所有的特征和行为。

例如:人:特征:身高、体重、血型、星座、姓名、性别、年龄等,行为:吃、睡、跑、走等

程序中对象是将现实中的对象进行模拟,注意:程序中并不会将现实对象的所有特征和行为均进行模拟,只会针对当前项目中所关注的特征和行为。例如:员工系统中的人(员工):特征:姓名、性别、年龄、部门、岗位、薪资、电话等,行为:出勤等

二、类

2.1 类的概念

具备有相同特征和行为的对象抽象出来的概念叫作类。

类与对象的关系:

类是对象的抽象,对象是类的具体化。类是对象的模板,对象根据类这个模板创建出来的实体。

三、程序中类的定义和对象的创建

3.1 类的定义
  1. // 定义一个类
  2. public class Dog {
  3. // 属性,变量
  4. // 直接定义在类中,不需要放到方法里
  5. String breed; // 品种
  6. int age; // 年龄
  7. String furColor; // 毛色
  8. String sex; // 性别
  9. // 方法
  10. // 吃
  11. public void eat() {
  12. System.out.println("正在吃...");
  13. }
  14. public void sleep() {
  15. System.out.println("正在睡...");
  16. }
  17. }

3.2 对象的创建和使用
public class TestMain {
    public static void main(String[] args) {
        // 创建对象
        Dog dog1 = new Dog(); // 类型为Dog,对象名为dog1,创建即分配空间的过程,使用new关键字
        // 不论是给属性赋值,还是调用其方法,都需要使用对象.
        // 给对象的属性赋不同的值
        dog1.age = 1;
        dog1.breed = "哈士奇";
        dog1.furColor = "黑白";
        dog1.sex = "公";
        System.out.println(dog1.breed);
        // 调用其方法
        dog1.eat();
        dog1.sleep();

        Dog dog2 = new Dog(); // 类型为Dog,对象名为dog2,创建即分配空间的过程,使用new关键字
        // 给对象的属性赋不同的值
        dog2.age = 2;
        dog2.breed = "德牧";
        dog2.furColor = "黑";
        dog2.sex = "公";
        System.out.println(dog2.breed);
        // 调用其方法
        dog2.eat();
        dog2.sleep();
    }
}

3.3 实例变量

对象又叫实例,属性又叫实例变量,这些变量不需要赋值既可使用。因为他们有默认值(与数组的默认值一样)。

实例变量与局部变量的区别:

局部变量 实例变量
定义位置 方法内部或参数 类的内部,与方法并列
默认值 没有,必须先赋值后使用 有默认值,与数组相同
作用域 定义行开始,到所在的结构结束 在本类中使用
命名冲突 不允许与其他局部变量相同 可以与局部变量同名,在方法中优先使用局部变量

3.3 实例方法

在类中可以定义实例方法,这些方法中不包含static关键字,必须使用对象才能调用。

方法分为两部分:

  • 方法的声明:方法的定义的部分,例如:public void eat()
  • 方法的实现:方法一对大括号以及里面的内容。
public void eat() // 方法声明
// 下面为方法的实现。    
{
    System.out.println("正在吃...");
}
public class Student {
    // 定义属性
    // 姓名name
    // 自定义默认值
    String name = "张三";
    // 年龄age
    int age = 20;
    // 性别sex
    String sex = "男";
    // 分数score
    int score = 80;

    // 定义方法
    // 打招呼,打印所有学生的属性sayHi
    public void sayHi() {
        System.out.println("Student [name=" + this.name + ", age=" + age + ", sex=" + sex + ", score=" + score + "]");
    }
}
public class TestStudent {
    public static void main(String[] args) {
        // 创建几个学生对象,赋值,并调用其打招呼方法
        Student student = new Student();
        student.name = "峰华";
        student.age = 18;
        student.sex = "男";
        student.score = 100;

        student.sayHi();
    }
}

3.4 this关键字

this表示当前创建的对象。谁调用该方法,就指代谁。

有三种用法:

  • 调用实例变量(属性)。当实例变量与局部变量同名时,使用this来调用实例变量。
  • 在方法中调用其他的实例方法时,可以使用this来调用(也可以省略)。
  • 在构造方法中调用其他的构造方法。
public class Dog {
    public void eat() {
        int age = 20;
        // this调用实例变量(属性)
        System.out.println("品种为: "+breed + ",年龄为:" +this.age + ", 毛色为:" +furColor+",性别为:"+sex+"的狗正在吃...");
        this.sleep(); // this调用其他实例方法
    }

    public void sleep() {
        System.out.println("正在睡...");
    }

    String breed; // 品种
    int age; // 年龄
    String furColor; // 毛色
    String sex; // 性别
}
public class Employee {
    public Employee() {
    }

    public Employee(String name, int age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    public Employee(String name, int age, String sex, int salary) {
        // 调用其他的构造方法
        this(name, age, sex);
//        this.name = name;
//        this.age = age;
//        this.sex = sex;
        this.salary = salary;
    }

    String name;
    // 年龄age
    int age;
    // 性别sex
    String sex;
    // 薪资
    int salary;
}

四、方法重载

在同一个类(父子类)中,方法名称相同,但是参数不同,叫做方法的重载。重载的好处是在调用这些同类型方法时,只需要记住一个方法名,会自动根据参数不同来调用不同的方法。

参数不同的情况:

  • 参数的类型不同
  • 参数的数量不同
  • 参数的顺序不同

注意:参数名称不同, 返回值类型不同或者static、public等不同均不构成重载。

public class TestOverload {
    public void m1(int n) {
        System.out.println("int");
    }

    public void m1(int n, int m) {
        System.out.println("int, int");
    }

    public void m1(String s) {
        System.out.println("String");
    }

    public void m1(String s, int n) {
        System.out.println("String, int");
    }

    public void m1(int n, String s) {
        System.out.println("int, String");
    }
}

五、构造方法

5.1 基本使用

构造方法是创建对象时调用的方法。使用new关键字调用,其与类名相同,没有返回值类型(不是void)。

在类中,如果没有写任何的构造方法,会默认存在一个无参的构造方法。

public class Student {
    public Student() {
        System.out.println("构造方法被调用");
    }
}

public class TestStudent {
    public static void main(String[] args) {
        // 创建学生对象时,会调用构造方法
        Student student = new Student();
    }
}

7_面向对象 - 图1

5.2 构造方法重载

在类中,构造方法可以重载。使用不同构造方法在创建对象时给属性赋值。避免在代码赋值过程中出错。

public class Employee {
    public Employee() {
    }

    public Employee(String name) {
        this.name =name;
    }

    public Employee(String name, int age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    public Employee(String name, int age, String sex, int salary) {
        // 调用其他的构造方法
        this(name, age, sex);
//        this.name = name;
//        this.age = age;
//        this.sex = sex;
        this.salary = salary;
    }

    String name;
    // 年龄age
    int age;
    // 性别sex
    String sex;
    // 薪资
    int salary;

    // 定义方法
    // 打招呼,打印所有学生的属性sayHi
    public void sayHi() {
        System.out.println("Employee [name=" + name + ", age=" + age + ", sex=" + sex + ", salary=" + salary + "]");
    }
}

5.3 默认构造方法机制

当类中没有定义任何构造方法时,会自动有一个默认的无参构造方法。如果在类中显式定义了一个有参构造方法,此时默认的无参构造方法就不存在。

此时,不能使用无参构造方法,会报错,解决方案有两种:

  • 改用有参构造方法
  • 在类中添加一个无参构造方法