文章目录
由来
为了引入“面向对象”这个概念,本文决定首先阐述一下计算机编程语言(下文简写为编程语言)的发展历程。
那么什么编程语言呢?有一句quote讲的很好。
算法是程序的灵魂,编程语言是塑造该灵魂的工具。
编程语言的发展,是随着计算机硬件的发展而发展的。硬件性能越高、体积越小、成本越低,应用到人类社会的场景就会越多。那么就需要更优越的算法和更有利于高效开发的编程语言,即更高级的编程语言。
编程语言至今大体发展了三代:第一代是机器语言,第二代是汇编语言,第三代是高级语言。
第一代语言:机器语言(相当于人类的原始阶段)
机器语言由0和1组成。当程序员想要编程时,需要对纸条打点,有点则为零,无点则为一,然后将纸条输入计算机中进行编译。但这对于人类来说,过于繁琐,不利于编出复杂的程序。
第二代语言:汇编语言(相当于人类的手工业阶段)
为了编程的方便,以及解决更加复杂的问题。程序员开始改进机器语言,使用英文缩写的助记符来表示基本的计算机操作,这些注记符构成了汇编语言的基础。汇编语言相当于人类的手工业社会,需要技术极其娴熟的工匠,所以开发效率仍然比较低下。
第三代语言:高级语言(相当于人类的工业阶段)
对于简单的任务,汇编语言可以胜任。但是随着计算机的发展,渗透到了工作生活的更多方面,一些复杂的任务出现了,汇编语言就显得力不从心了。于是,出现了高级语言。像我们熟知的C、C++、Java等等都是高级语言。高级语言允许程序员使用接近日常英语的指令来编写程序。
从计算机语言的发展史来看:越高级的语言,越接近人的思维,人使用起来就越方便。所以,未来计算机语言的发展,肯定会向着人类更加容易理解的方向,越来越接近于人类的生活。
编程范式
范式,即思维方式。而编程范式就是编写程序时用到的思维方式。该部分会按发展顺序列举一些比较经典的编程范式,从而引出“面向对象”编程范式。
面向机器(英语:Machine-oriented),通过指令直接操作底层硬件内存单元、寄存器等,以此实现计算、硬件驱动及控制等功能。
面向结构(英语:Structure-oriented),将实现一定功能的指令集进行封装,形成子程序、块等功能结构,通过调用功能模块代替逐字逐句地编写程序。
面向过程(英语:Procedure-oriented),分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用时依次调用。并结合判断、选择、循环流程控制语句简化问题的解决方式。
面向对象(英语:Object-oriented),将处理问题的方式从分析解决步骤转移到分析处理对象的层面上来。将问题涉及的数据和解决步骤全权分配给对象。通过管理对象的方式处理待解决的问题。
类与对象
类
类是一个抽象的数据类型,用来描述一类对象的状态数据和行为方法。下面代码写的是一个比较完整的类:
package cn.charliejohn.oop;
import java.io.Serializable;
/**
* @deprecated 一个比较完整的类
* @author charlie
* @date 2021/05/17 15:28
*/
public class JavaClass extends Object implements Serializable {
private static final long serialVersionUID = 1L;
private int value;
public JavaClass(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public static void main(String[] args) {
System.out.println("The value of JavaClass is "+new JavaClass(3000).getValue()+".");
}
}
成员变量
定义在类中,方法体之外的变量,可以是基本数据类型和引用类型。这种变量在创建对象的时候实例化。成员变量可以被成员方法、构造方法和特定类的语句块所访问。
构造方法
用于初始化对象的状态数据。
注意:
- 与类名相同
- 没有返回值
成员方法
用于实现对数据的操作。
对象
对象是一个基于类实例化后的一个具体模型,其拥有具体的状态数据和行为方法。
经典实例的修饰符
this
即对象本身。
super
即对象的父类。
经典类、函数及变量的修饰符
static
static,即静态的。
注意:
-
其修饰的变量及函数又称类变量和类方法
-
它们会在编译时加载到内存里,可以通过类名直接访问
-
不同对象的类变量指向同一内存空间,相当于云同步
-
类方法不能访问非类变量,即静态方法只能访问静态变量
-
外部类不能为静态
-
静态代码区语法为:
static {}
final
final,即最终的。
注意:
- 无法被覆盖
- 无法被修改
- 无法被继承
class文件
一个类对应一个class文件,和java文件的数量无关,也与内部类或者外部类无关。
封装
封装就是把抽象出的数据和方法封装到对象内部,外界只有通过被授权的方法才能对这些数据及方法进行操作。
继承
通过继承可以获得部分父类的成员变量和成员方法,从而提高代码的复用率。
访问权限修饰符
访问级别 | 访问控制修饰符 | 同类 | 同包 | 子类 | 不同包 |
---|---|---|---|---|---|
公开 | public | √ | √ | √ | √ |
受保护 | protected | √ | √ | √ | × |
默认 | 没有修饰符 | √ | √ | √ or ×(见说明) | × |
私有 | private | √ | × | × | × |
说明:需要特别说明“无修饰符”这个情况,子类能否访问父类中无修饰符的变量/方法,取决于子类的位置。如果子类和父类在同一个包中,那么子类可以访问父类中的无修饰符的变量/方法,否则不行。
重载(overload)
类的同一种功能的多种实现,具体采用哪种取决于调用者传递的参数。
注意:
- 方法名相同
- 方法的参数类型、个数、顺序至少有一项不同
- 方法的返回类型可以不同,但不可以仅仅返回类型不同
- 方法的修饰符可以不同,但不可以仅仅修饰符不同
重写/覆盖(override)
子类对父类中某成员方法的改造。
注意:
- 名称、返回类型、参数都一致
- 方法体不同
- 子类方法不能缩小父类方法的访问权限
多态
通过指向父类的指针,来调用不同子类中实现的方法。
注意:
- 父类引用指向子类对象,即父类对象不能赋予子类引用。
抽象类和接口的区别
语法维度 | 抽象类 | 接口 |
---|---|---|
定义关键字 | abstract | interface |
子类继承或实现关键字 | extends | implements |
方法实现 | 可以有 | 不能有,但在JD K8 及之后,允许有d efault 实现 |
方法访问控制符 | 无限制 | 有限制,默认是public abstract类型 |
属性访问控制符 | 无限制 | 有限制,默认是public static final类型 |
静态方法 | 可以有 | 不能有 |
static{}静态代码块 | 可以有 | 不能有 |
本类型之间扩展 | 单继承 | 多继承 |
本类型之间扩展关键字 | extends | extends |
枚举
Java 枚举是一个特殊的类,一般表示一组常量,如三基色:
enum Color
{
RED, GREEN, BLUE;
}
实际应用当中很少用到。