面向对象特性介绍(封装,继承,多态),与 C++区别

架构真经

共 2567字,需浏览 6分钟

 · 2022-01-02

面向过程让计算机有步骤地顺序做一件事,是过程化思维,使用面向过程语言开发大型项目,软件复用和维护存在很大问题,模块之间耦合严重。面向对象相对面向过程更适合解决规模较大的问题,可以拆解问题复杂度,对现实事物进行抽象并映射为开发对象,更接近人的思维。例如开门这个动作,面向过程是 open(Door door),动宾结构,door 作为操作对象的参数传入方法,方法内定义开门的具体步骤。面向对象的方式首先会定义一个类 Door,抽象出门的属性(如尺寸、颜色)和行为(如 open 和 close),主谓结构。面向过程代码松散,强调流程化解决问题。面向对象代码强调高内聚、低耦合,先抽象模型定义共性行为,再解决实际问题。

  • 封装:把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。封装是面向对象的特征之一,是对象和类概念的主要特性。简单的说,一个类就是一个封装了数据以及操作这些数据的代码的逻辑实体。在一个对象内部,某些代码或某些数据可以是私有的,不能被外界访问。通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分。

  • 继承:是指可以让某个类型的对象获得另一个类型的对象的属性的方法。它支持按级分类的概念。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。继承的过程,就是从一般到特殊的过程。要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。继承概念的实现方式有二类:实现继承与接口继承。实现继承是指直接使用基类的属性和方法而无需额外编码的能力;接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力;

  • 多态:是指一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。

    与 C++的共同点:C++和 Java 都是强类型语言,都有类的概念,并且都有 private、protected、public 关键字来限定属性、方法的访问权限。

    与 C++的区别:

    (1)封装的区别:C++和 Java 的 private、protected、public 表示的权限范围不同。C++中,private 表示只能在类自己的方法中访问;protected 表示类自己和类的子类可以访问;public 表示任何地方均可访问。Java 中,private 表示类自己的方法中访问;protected 表示类自己和类的子类;public 表示任何地方均可以访问;不加任何限定字表示同一包下的其他类可以访问。

    (2)继承的区别

    C++的继承方式

    Java 只保留了 public 继承的这种继承方式,从替换原则的角度来说,这样实际上更符合面向对象的思想。C++可以继承多个类,继承之后就拥有了所有子类的属性和方法。Java 只能继承自一个类,但可以实现多个接口。

    另外 Java 语言本身除了提供了 Java 语法外,还和 Java 标准库进行了高度的结合,所有的 Java类,都是 Object 类的子类。并且不需要程序员显示的继承 Object 类,编译机默认所有类均直接或间接的继承自 Object 类。所以说 Java 是单根继承的。

    不管是 C++和 Java,为了实现多态,都需要将对象的方法进行晚绑定,即在运行时决定调用对象的哪一个方法,而不是在编译期间确定。C++方法的晚绑定是通过虚函数实现。虚函数又分为纯虚函数和虚函数,定义纯虚函数的类可以不实现它,而交给子类区实现,定义虚函数的类需要同时实现它。无论是虚函数还是纯虚函数,编译器在编译时,不会直接决定该执行哪一个函数,而是通过虚函数表中的函数指针去调用。如此实现了对象方法调用的晚绑定。Java 的除了 private 方法和 static 之外的所有方法均为晚绑定,所以 Java 中没有虚函数的概念。

多态的分类:编译时多态(静态多态,重载)和运行时多态(动态多态)

多态的实现方法:子类继承父类(extends)和类实现接口(implements) 多态的实现原理:Java 的方法调用方式:Java 的方法调用有两类,动态方法调用与静态方法调用。静态方法调用是指对于类的静态方法的调用方式,是静态绑定的;而动态方法调用需要有方法调用所作用的对象,是动态绑定的。类调用(invokestatic) 是在编译时刻就已经确定好具体调用方法的情况,而实例调用invokevirtual) 则是在调用的时候才确定具体的调用方法,这就是动态绑定,也是多态要解决的核心问题。

JVM 的方法调用指令有四个,分别是 invokestatic,invokespecial,invokesvirtual 和 invokeinterface。前两个是静态绑定,后两个是动态绑定的。本文也可以说是对于 JVM 后两种调用实现的考察。

常量池(constant pool):常量池中保存的是一个 Java 类引用的一些常量信息,包含一些字符串常量及对于类的符号引用信息等。Java 代码编译生成的类文件中的常量池是静态常量池,当类被载入到虚拟机内部的时候,在内存中产生类的常量池叫运行时常量池。常量池在逻辑上可以分成多个表,每个表包含一类的常量信息,本文只探讨对于 Java 调用相关的常量池表。

方法表与方法调用:方法表是动态调用的核心,也是 Java 实现动态调用的主要方式。它被存储于方法区中的类型信息,包含有该类型所定义的所有方法及指向这些方法代码的指针,注意这些具体的方法代码可能是被覆写的方法,也可能是继承自基类的方法。


浏览 30
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报