什么是面向对象
- 面向对象编程(OOP)
- 面向对象编程的本质就是:以类的方式组织代码,以对象的形式封装数据
- 三大特征:封装、继承、多态
- 从认识论角度考虑是先有对象后有类,对象,是具体的事物。类,是抽象的,是对对象的抽象
- 从代码运行角度考虑是先有类后有对象。类是对象的模板
对象的创建和分析
类和对象的关系
类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物
- 动物、植物、手机、电脑...
- Person类、Pet类、Car类等,这些类都是用来描述/定义某一类具体的事物应该具备的特点和行为。
对象是抽象概念的具体实例
- 张三就是人的一个具体实例,张三家里的旺财就是狗的一个具体实例。
- 能够体现出特点,展现出功能的是具体的实例,而不是一个抽象的概念。
对象的创建与初始化
- 使用new关键字创建对象
- 使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用
- 类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下两个特点:
- 必须和类的名字相同;
- 必须没有返回类型,也不能写void
构造器
- 构造器:和类名相同;没有返回值
- 作用:new本质是在调用构造方法;初始化对象的值
- 注意点:定义有参构造之后,如果想使用无参构造,需要显示的定义一个无参构造
代码实例:
/**
* @ClassName Student
* @Description : 学生类
* @Author : ZG
* @Date: 2024-06-18 14:38
*/
public class Student {
private int age;
private String name;
public Student() {
}
public Student(int age, String name) {
this.age = age;
this.name = name;
}
}
面向对象的三大特征
封装
- 我们程序设计要追求“高内聚,低耦合”。高内聚:就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用。
- 封装(数据的隐藏):通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。记住这句话就够了,属性私有,get/set。
- 封装的优点:1.提高程序的安全性,保护数据;2.隐藏代码的实现细节;3.统一接口;4.系统可维护增加了
继承
什么是继承
- 继承是面向对象对象三大特征之一,可以让类与类之间产生父子关系。
- 可以把多个子类中的重复代码抽取到父类中,子类可以直接使用,减少代码冗余,提高代码的复用性。
继承的格式
public class 子类 extends 父类{}
继承的好处
子类可以得到父类的属性和行为,子类可以使用; 子类可以在父类的基础上新增其他功能,子类更强大;
继承的特点
- java只支持单继承,不支持多继承,但是支持多层继承;
- 每一个类都直接或间接的继承于Object类;
子类到底能继承父类中的哪些内容
| 成员 | 非私有 | 私有 |
|---|---|---|
| 构造方法 | 不能 | 不能 |
| 成员变量 | 能 | 能 |
| 成员方法 | 能 | 不能 |
- 继承中成员变量的访问特点:就近原则;先在局部位置找,本类成员位置找,父类成员位置找,逐级往上。
- 继承中成员方法的访问特点:this调用,就近原则;super调用,直接找父类。
继承中构造方法的访问特点
- 父类中的构造方法不会被子类继承
- 子类中所有的构造方法默认先访问父类中的无参构造,再执行自己。
为什么?
- 子类在初始化的时候,有可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据。
- 子类初始化之前,一定要调用父类构造方法先完成父类数据空间的初始化。
继承中构造方法的访问特点
- 子类不能继承父类的构造方法,但是可以通过super调用
- 子类构造方法的第一行,有一个默认的super()
- 默认先访问父类中无参构造方法,再执行自己
- 如果想要方法访问父类的有参构造,必须手动书写
super关键字
- super理解为:父类的
- super可以用来调用:属性、方法、构造器
super调用属性和方法
- 我们可以在子类的方法或构造器中。通过使用super.属性或super.方法的方式,显式的调用父类中声明的属性或方法。但是,通常情况下,我们习惯省略super。
- 当子类和父类中定义了同名的属性时,我们要想在子类中调用父类中声明的属性,则必须显示的使用super.属性的方式,表明调用的是父类中声明的属性。
- 当子类重写了父类中的方法以后,我们想在子类的方法中调用父类中被重写的方法时,则必须显式的使用super.方法的方式,表明调用的是父类中被重写的方法。
super调用构造器
- 我们可以在子类的构造器中显示的使用super(形参列表)的方式,调用父类中声明的指定的构造器。
- super(形参列表)的使用,必须声明在子类构造器的首行。
- 我们在类的构造器中,针对于this(形参列表)或super(形参列表)只能二选一,不能同时出现。
- 在构造器的首行,没有显示的声明super(形参列表),则默认调用的是父类中空参的构造器:super()
- 在类的多个构造器中,至少有一个类的构造中使用了super(形参列表)调用了父类中的构造器
重写
- 需要有继承关系,子类重写父类的方法
- 方法名必须相同
- 参数列表必须相同
- 修饰符:范围可以扩大但是不能缩小,public>peotected>缺省>private
- 抛出的异常:范围可以缩小,但是不能扩大
- 重写,子类的方法和父类必要一致;方法体不同
- 为什么需要重写:父类的功能,子类不一定需要,或者不一定满足
父类中不能被重写的方法
- 带static修饰的方法(static方法属于类,不属于实例)
- 带final修饰的方法(final常量修饰符)
- 带private修饰的方法,私有的方法不能重写
多态
定义:
- 多态是同一个行为具有不同的表现形式或形态的能力
- 同一方法可以根据发送的对象的不同而采用不同的行为方式
多态就是事物的多种形态,一个对象在不同条件下所表现的不同形式
多态的存在条件:
- 继承或是实现:在多态中必须存在有继承或实现关系的子类和父类
- 方法的重写:子类对父类中的某些方法进行重新定义(重写,使用@Override注解进行重写)
- 基类引用指向派生类对象,即父类引用指向子类对象,父类类型:指子类对象继承的父类类型,或实现的父接口类型
多态的格式:
- 父类类型 变量名=new 子类型();
- 然后通过 变量量.方法名()调用在子类重写的方法
- 多态体现为父类引用变量可以指向子类对象:定义了一个父类类型的引用,指向新建的子类类型的对象,由于子类是继承他的父类的,所以父类类型引用是可以指向子类类型的对象的
public class Test01 {
public static void main(String[] args) {
Person student = new Student();
student.eat();
}
}
多态中的成员特点:
多态成员变量:编译运行看左边 多态成员方法:编译看左边,运行看右边
多态的特点:
- 子类和父类存在同名的成员变量时,访问的是父类的成员变量
- 子类和父类存在同名的非静态成员方法时,访问的是子类中重写的方法
- 子类和父类存在同名的静态成员变量成员方法时,访问的是父类的成员函数
- 不能访问子类中独有的方法
引用类型转换:
- 向上转型:子类向父类向上转换(自动转换)的过程,这个过程是默许的,当父类引用指向子类对象时,就是向上转型
- 向下转型:向下转型是父类向子类转换的过程,这个过程需要强制转换
- 向下转型的问题:虽然可以通过向下转型可以调用子类独有的方法,但也会产生下面的问题ClassCastException类型转换异常。想要避免这种问题就要使用instanceof关键字。
public class Test01 {
public static void main(String[] args) {
//如果变量student属于该数据类型或者是其子类,返回true
//如果变量不student属于该数据类型或者是其子类,返回true
Person student = new Student();
boolean flag = student instanceof Person;
}
}