面向对象
一、对象
1.1 对象的概念
在程序员世界中,万物皆为对象。
1.2 面向对象
面向过程:采用过程(步骤的方式)来解决问题。
面向对象:在解决问题过程中,考虑有哪些对象参与,再思考这些对象在当前问题中有哪些需要用到特征和行为,根据这些特征和行为进行现实中的模拟,得到最终的结果。
面向接口:在开发过程中,由于分工协作,需要将自己的模块提供相应的接口,其他模块在开发时,应该根据接口来进行相应的开发。
面向服务:在非常复杂的企业级的项目中,会将各个功能封装相应的服务,提供给其他(外部)的调用者调用,叫做面向服务的编程。
将大象放入冰箱。
面向过程的解决方案:
第一步:打开冰箱
第二步:把大象塞到冰箱中
第三步:关上冰箱
需要宏观的考虑每一步的处理,以及对应的解决方案,针对于简单的问题的解决可以使用此方式。面向对象的解决方案:
参与的对象:
冰箱:特征:容积、入口
大象:特征:大小
出力者:行为:放
针对于复杂的问题,可以进行合理分工,可以模拟现实中的细节,主要要来解决企业中的复杂业务处理流程。
1.3 对象的特点
对象分为特征和行为两部分。
特征:又叫属性,一般是名词。对象有(具备)什么
行为:也叫方法,一般是动词。对象能做什么
1.4 现实对象和程序中对象
现实生活中的对象具备有所有的特征和行为。
例如:人:特征:身高、体重、血型、星座、姓名、性别、年龄等,行为:吃、睡、跑、走等
程序中对象是将现实中的对象进行模拟,注意:程序中并不会将现实对象的所有特征和行为均进行模拟,只会针对当前项目中所关注的特征和行为。例如:员工系统中的人(员工):特征:姓名、性别、年龄、部门、岗位、薪资、电话等,行为:出勤等
二、类
2.1 类的概念
具备有相同特征和行为的对象抽象出来的概念叫作类。
类与对象的关系:
类是对象的抽象,对象是类的具体化。类是对象的模板,对象根据类这个模板创建出来的实体。
三、程序中类的定义和对象的创建
3.1 类的定义
// 定义一个类
public class Dog {
// 属性,变量
// 直接定义在类中,不需要放到方法里
String breed; // 品种
int age; // 年龄
String furColor; // 毛色
String sex; // 性别
// 方法
// 吃
public void eat() {
System.out.println("正在吃...");
}
public void sleep() {
System.out.println("正在睡...");
}
}
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();
}
}
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 默认构造方法机制
当类中没有定义任何构造方法时,会自动有一个默认的无参构造方法。如果在类中显式定义了一个有参构造方法,此时默认的无参构造方法就不存在。
此时,不能使用无参构造方法,会报错,解决方案有两种:
- 改用有参构造方法
- 在类中添加一个无参构造方法