Java是一门面向对象编程语言,那么什么是面向对象呢?
百度百科中这样描述:
面向对象(Object Oriented)是软件开发方法。面向对象的概念和应用已超越了程序设计和软件开发,扩展到如数据库系统、交互式界面、应用结构、应用平台、分布式系统、网络管理结构、CAD技术、人工智能等领域。面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物。
面向对象是相对于面向过程来讲的,面向对象方法,把相关的数据和方法组织为一个整体来看待,从更高的层次来进行系统建模,更贴近事物的自然运行模式。
这里我们用木匠打一个比方,一个“面向对象”的木匠始终关注的是所制作的椅子,第二位才是所使用的工具;而一个“非面向对象的”木匠首先考虑的是所使用的工具。
面向对象的内容有:
-
类 ->定义了一件事物的抽象特点。类的定义包含了数据的形式以及对数据的操作。
-
对象 ->是类的实例。
-
成员变量 ->成员变量 − 定义在类内部的变量。该变量的值对外是不可见的,但是可以通过成员函数访问,在类被实例化为对象后,该变量即可称为对象的属性。
-
成员函数(方法) ->定义在类的内部,可用于访问对象的数据。
-
封装
-
继承
-
多态
-
父类 ->可以被其他类继承,将这种类称为基类,父类或超类。
-
子类 ->继承其他类的类,称为子类或者派生类。
-
接口 ->是指对协定进行定义的引用类型。其他类型实现接口,以保证它们支持某些操作。接口指定必须由类提供的成员或实现它的其他接口。
-
重载 ->函数或者方法有同样的名称,参数类型或者参数个数不同。
所有的面向对象编程语言的三大特性是: -
封装
-
继承
-
多态
(!!!注意:面向对象编程语言而不是Java语言的特性)。
我们具体总结三大特性。
封装
封装顾名思义也就是把一个事物包装起来,不被外界看到。在程序中封装就是隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别;将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体。
这样做的目的是使类的使用者不必关系类内部具体的实现方法,降低了学习成本。也达到了对成员访问权限的合理控制,使不同类之间的相互影响减少到最低限度,进而增强数据的安全性和简化程序的编写工作。打个比方说:我们不需要具体清楚为什么我们在键盘上按下0键,屏幕上就会打印出一个0,我们只需要知道我们按什么屏幕上就会打印出什么这就够了。
继承
代码中创建的类, 主要是为了抽象现实中的一些事物(包含属性和方法). 有的时候客观事物之间就存在一些关联关系, 那么在表示成类和对象的时候也会存在一定的关联.继承是一种 is -> a 的关系。
- 使用 extends 指定父类.
- Java 中一个子类只能继承一个父类 (而C++/Python等语言支持多继承).
- 子类会继承父类的所有public 的字段和方法.
- 对于父类的 private 的字段和方法, 子类中是无法访问的.
- 子类的实例中, 也包含着父类的实例.可以使用 super 关键字得到父类实例的引用.
如果我们将父类中的成员属性设为private, 子类不能访问. 但是设成 public, 又违背了我们 “封装” 的初衷。我们可以使用 protected 关键字进行修饰。
- 对于类的调用者来说, protected 修饰的字段和方法是不能访问的
- 对于类的 子类 和 同一个包的其他类 来说, protected 修饰的字段和方法是可以访问的
当final 关键字修饰一个类时,它代表的含义就是这个类不能再被继承。
还有一种类之间的关系类似于继承,就是组合,它是一种 has -> a 的关系。
类似一个 team 类,它的可以有 teamleader 类,也有 member。一个队伍中既有队长,也有队员。
多态
1.向上转型
用一个父类的引用,指向一个子类的实例被称为向上转型。
2.动态绑定
父类和子类中有一个相同的方法(除了具体实现内容不同,其他都相同),在Java中调用这个方法时, 究竟执行了哪段代码 (是父类方法的代码还是子类方法的代码) , 要看究竟这个引用指向的是父类对象还是子类对象. 这个过程是程序运行时决定的(而不是编译期), 因此称为 动态绑定.
3.方法重写
子类实现父类的同名方法, 并且参数的类型和个数完全相同, 这种情况称为 覆写/重写/覆盖(Override).
关于重写的注意事项
1.重写和重载完全不一样. 不要混淆(思考一下, 重载的规则是啥?)
2.普通方法可以重写, static 修饰的静态方法不能重写.
3.重写中子类的方法的访问权限不能低于父类的方法访问权限.
什么是多态?
当类的调用者在使用类时,不必关心这个类是啥类。也不需要关心是哪个子类的实例,只需要知道类中有某个方法直接调用就行。
多态也是封装的更进一步,之前封装是为了让类的调用者不需要知道类的实现细节(还是得知道这个是啥类),多态这里类的调用者都不需要知道这是个啥类,只需要知道类中有某个方法就行。