对于面向对象的简单理解

article/2025/9/18 12:07:58

引言

一直都想写一篇关于面向对象的文章,但是由于之前自己也是一知半解所以也就一直没有付出行动。关于面向对象的这类文章网上已经有很多大牛写过了,在这里呢我也就不班门弄斧了。就简单的说一下我的理解,话不多说接下来进入主题。

什么是面向对象

这里的面向对象主要说的是java语言。

面向对象:把数据及对数据的操作方法放在一起,作为一个相互依存的整体——对象。对同类对象抽象出其共性,形成类。类中的大多数数据,只能用本类的方法进行处理。类通过一个简单的外部接口与外界发生关系,对象与对象之间通过消息进行通信。程序流程由用户在使用中决定。

上面那段解释相信大家在书本上都有看过,可是这样的解释对于一些初学者或者菜鸟来说还是有点难以理解的。

其实怎么说呢,面向对象其实很简单。很多人会说万物皆对象,那么万物皆对象这句话是什么意思呢?简单点来说就是世间万物都可以作为对象。
举一个简单的例子:
比如说你想去买一台电脑可是你对电脑又不怎么了解,什么cpu啊、处理器、内存、显卡等等。这个时候你就需要找一个懂电脑的和你一起去买(省的被商家骗了)而你找人帮你一起去买电脑的这个行为就可以理解为面向对象。
再比如说一个比较经典的例子:要把大象放到冰箱里应该怎么做?很多人应该会想到,首先把冰箱门打开、然后把大象放进去、最后把门关上。这样就把大象放进去了。从上面的叙述我们可以得出从把冰箱门打开、然后把大象放进去、最后把门关上,这其实就是一个过程,最后的结果就是把大象放到了冰箱里。在这个过程中我们可以把冰箱看成一个对象而打开冰箱门,把大象放进去,然后把冰箱门关上,我们都可以把这一系列动作看成是冰箱这个对象的方法,而我们要把大象放到冰箱里我们只需要调用冰箱的这些方法就行了,至于说冰箱怎么实现这些方法的你没有必要知道,你所要知道的就是结果:大象放到了冰箱里。这就是面向对象。

面向对象的三大特征

1.封装
概念:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
好处:• 将变化隔离。• 便于使用。• 提高重用性。• 提高安全性。
封装原则:
• 将不需要对外提供的内容都隐藏起来。
• 把属性都隐藏,提供公共方法对其访问。
Java中可以通过对类的成员设置一定的访问权限,实现类中成员的信息隐藏。

private:类中限定为private的成员,只能被这个类本身访问。如果一个类的构造方法声明为private,则其它类不能生成该类的一个实例。
default:类中不加任何访问权限限定的成员属于缺省的(default)访问状态,可以被这个类本身和同一个包中的类所访问。
protected:类中限定为protected的成员,可以被这个类本身、它的子类(包括同一个包中以及不同包中的子类)和同一个包中的所有其他的类访问。
public:类中限定为public的成员,可以被所有的类访问。
这里写图片描述

class Student {private   String name;//声明属性 ,并设为私有类型,起到封装的作用private   int age;public Student(String name,int age ) { //构造函数,分别给name、age赋值this.name= name;// :this代本类对象的引用this.age= age;}public String getName() { //设置getter方法,因为变量设为了私有,对象无法访问类中的属性,需要用getter方法获取变量return name;}public void setName(String name) { //设置setter方法,因为变量设为了私有,对象无法访问类中的属性,需要用setter方法给变量赋值this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}

2.继承
子类的对象拥有父类的全部属性与方法,称作子类对父类的继承。
Java中父类可以拥有多个子类,但是子类只能继承一个父类,称为单继承。

 class SubDemo extends Demo{} //这是对的• class SubDemo extends Demo1,Demo2...//这是错的Java支持多层继承(继承体系)• class A{}• class B extends A{}• class C extends B{}

继承的好处就是:实现了代码的复用。
Java中所有的类都是通过直接或间接地继承java.lang.Object类得到的。
子类不能继承父类中访问权限为private的成员变量和方法。
子类可以重写父类的方法,即命名与父类同名的成员变量。

Java中通过super来实现对父类成员的访问,super用来引用当前对象的父类。super 的使用有三种情况:
访问父类被隐藏的成员变量,如:super.variable;
调用父类中被重写的方法,如:super.Method([paramlist]),super()调用父类构造方法;
调用父类的构造函数,如:super([paramlist]);
比如:

class Fu { //父类int age=20;String name="fu";public void show() {System.out.println("姓名:"+name+"   年龄:"+age);}}class Zi extends Fu{//子类Zi继承了父类Fuint score=90;//增加了新的属性int age= super.age+1;//使用super标记父类中的元素,修改了Fu中age的值public void show() {//重写了父类中的方法(  覆盖时,子类方法权限一定要大于等于父类方法权限,静态只能覆盖静态。)System.out.println("姓名:"+name+"   年龄:"+age+"   分数:"+ score);// Zi继承了Fu,所以Fu中的属性name和age在Zi可以直接使用}
}public class Demo{public static void main(String[] args) {Fu fu = new Fu();//声明一个Fu对象Zi zi =new Zi()//声明一个Zi对象Fu.show();Zi.show();}}

程序运行结果是:
姓名:fu 年龄:20
姓名:fu 年龄:21 分数:90

super和this的用法相同:this代表本类应用 ;super代表父类引用 。当子父类出现同名成员时,可以用super进行区分 ,子类要调用父类构造函数时,可以使用super语句。

在子类覆盖方法中,继续使用被覆盖的方法可以通过super.函数名获取。

注意:

1 . 子类中所有的构造函数默认都会访问父类中空参数的构造函数,因为每一个构造函数的第一行都有一条默认的语句 super();子类会具备父类中的数据,所以要先明确父类是如何对这些数据初始化的。当父类中没有空参数的构造函数时,子类的构造函数 必须通过this或者super语句指定要访问的构造函数。

2 . 覆盖时,子类方法权限一定要大于等于父类方法权限静态只能覆盖静态。父类中的私有方法不可以被覆盖。

3.被final修饰的类是一个最终类,不可以被继承。

被final修饰的方法是一个最终方法,不可以被覆盖。

被final修饰的变量是一个常量,只能赋值一次

内部类只能访问被final修饰的局部变量。

4 . 继承与重载:一是子类与父类的关系,二是重载方法的调用问题。

3.多态
方法的重写、重载与动态连接构成多态性。Java只允许单继承,这样做虽然保证了继承关系的简单明了,但是功能上有很大的限制,所以,Java引入了多态性的概念。此外,抽象类和接口也是解决单继承规定限制的重要手段。同时,多态也是面向对象编程的精髓所在。

多态性:发送消息给某个对象,让该对象自行决定响应何种行为。

通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用。

java 的这种机制遵循一个原则:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。

1. 如果a是类A的一个引用,那么,a可以指向类A的一个实例,或者说指向类A的一个子类。

2. 如果a是接口A的一个引用,那么,a必须指向实现了接口A的一个类的实例。要理解多态性,首先要知道什么是“向上转型”。
  
子类Cat继承了Animal类,那么后者就是前者是父类。

Cat c = new Cat();//实例化一个Cat的对象,

Animal a = new Cat();//定义了一个Animal类型的引用,指向新建的Cat类型的对象

由于Cat是继承自它的父类Animal,所以Animal类型的引用是可以指向Cat类型的对象的。那么这样做的什么意义是:因为子类是对父类的一个改进和扩充,所以一般子类在功能上较父类更强大,属性较父类更独特,

定义一个父类类型的引用指向一个子类的对象既可以使用子类强大的功能,又可以抽取父类的共性。

所以,父类类型的引用可以调用父类中定义的所有属性和方法,但是对于子类中定义而父类中没有的方法,它是无可奈何的;

同时,父类中的一个方法只有在在父类中定义而在子类中没有重写的情况下,才可以被父类类型的引用调用;

对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态连接。
  
  比如:

class Father{public void func1(){func2();}public void func2(){//这是父类中的func2()方法,因为下面的子类中重写了该方法//所以在父类类型的引用中调用时,这个方法将不再有效//取而代之的是将调用子类中重写的func2()方法System.out.println("AAA");}}class Child extends Father{//func1(int i)是对func1()方法的一个重载//由于在父类中没有定义这个方法,所以它不能被父类类型的引用调用//所以在下面的main方法中child.func1(68)是不对的public void func1(int i){System.out.println("BBB");}//func2()重写了父类Father中的func2()方法//如果父类类型的引用中调用了func2()方法,那么必然是子类中重写的这个方法public void func2(){System.out.println("CCC");}}public class PolymorphismTest {public static void main(String[] args) {Father child = new Child();child.func1();//打印结果将会是什么?//此方法是错误的,父类中没有此方法。// child.func1(68)}}

这是个很典型的多态的例子。子类Child继承了父类Father,并重载了父类的func1()方法,重写了父类的func2()方法。重载后的func1(int i)和func1()不再是同一个方法,由于父类中没有func1(int i),那么,父类类型的引用child就不能调用func1(int i)方法。而子类重写了func2()方法,那么父类类型的引用child在调用该方法时将会调用子类中重写的func2()。

所以程序运行结果应该是“CCC”。

实现多态,有二种方式,覆盖(override),重载(overload)。

覆盖,是指子类重新定义父类的虚函数的做法。它是覆盖了一个方法并且对其重写,以求达到不同的作用。在覆盖要注意以下的几点:
1、覆盖的方法的标志必须要和被覆盖的方法的标志完全匹配,才能达到覆盖的效果;
2、覆盖的方法的返回值必须和被覆盖的方法的返回一致;
3、覆盖的方法所抛出的异常必须和被覆盖方法的所抛出的异常一致,或者是其子类;
4、被覆盖的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行覆盖。

重载,是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。它是指我们可以定义一些名称相同的方法,通过定义不同的输入参数来区分这些方法,然后再调用时,在使用重载要注意以下的几点:
1、在使用重载时只能通过不同的参数样式。例如,不同的参数类型,不同的参数个数,不同的参数顺序(当然,同一方法内的几个参数类型必须不一样,例如可以是fun(int,float),但是不能为fun(int,int));
2、不能通过访问权限、返回类型、抛出的异常进行重载;
3、方法的异常类型和数目不会对重载造成影响;
4、对于继承来说,如果某一方法在父类中是访问权限是priavte,那么就不能在子类对其进行重载,如果定义的话,也只是定义了一个新方法,而不会达到重载的效果。

多态也有弊端:当父类引用指向子类对象时,虽然提高了扩展性,但是只能访问父类中具备的方法,不可以访问子类中特有的方法。(前期不能使用后期产生的功能,即访问的局限性)
(如果有错误希望大家一起探讨!)


http://chatgpt.dhexx.cn/article/qkvJIQ3w.shtml

相关文章

js面向对象理解

ECMAScript 有两种开发模式:1.函数式(过程化),2.面向对象(OOP)。面向对象的语言有一个标志,那就是类的概念,而通过类可以创建任意多个具有相同属性和方法的对象。但是,ECMAScript 没有类的概念,因此它的对象…

Python面向对象理解

一,初始面向对象. 面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西。 优点是:极大的降低了写程序的复杂度…

面向对象理解——多态

何为多态 定义: 多态是指不同的子类在继承父类后分别都重写覆盖了父类的方法,即父类同一个方法,在继承的子类中表现出不同的形式。系统在运行时(而非编译时),能够根据其类型确定调用哪个重载的成员函数的能…

面向对象的理解及相关概念(封装,继承,多态)

前言 面向对象程序设计(OOP)是当今主流的程序设计范性,它取代了结构化或过程式编程技术。 一、面向对象是什么? 1、定义: 面向对象就是:把数据及对数据的操作方法放在一起,作为一个相互依存…

面向对象的理解

一、什么是面向对象? 对 Java 语言来说,一切皆是对象。把现实世界中的对象抽象地体现在编程世界中,一个对象代表了某个具体的操作。一个个对象最终组成了完整的程序设计,这些对象可以是独立存在的,也可以是从别的对象继…

面向对象理解

1.早期发展 面向对象(Object Oriented,OO)是软件开发方法。面向对象的概念和应用已超越了程序设计和软件开发,扩展到如数据库系统、交互式界面、应用结构、应用平台、分布式系统、网络管理结构、CAD技术、人工智能等领域。面向对象是一种对现实世界理解和抽象的方法…

error: unknown file type '.pyx' (from 'pycocotools/_mask.pyx')

在 YOLO v3模型中运用 cocoapi 进行评估模型,安装时报错显示: building pycocotools._mask extension error: unknown file type .pyx (from pycocotools/_mask.pyx) make: *** [all] Error 1可能的解决方法:   运行的 Python 版本不对。 …

sklearn/tree/_criterion.pyx

注解: criterions分为几类,其中有classification criterions与regression criterions。classification criterions是针对离散的,regression criterions是针对连续分布的 本文主要讲解一下RegressionCriterion。 RegressionCriterion用于回归树(Regression Tree 回归树)中…

python中导入.pyx文件的问题解决

已经几次遇到这种问题了, 里面的region指的是一个.pyx文件。 ImportError: cannot import name region from toolkit.utils (D:\******\RPN\pysot-master\toolkit\utils\__init__.py) 解决方案: 创建一个setup.py文件,一般如果是搬运的话里面会有&…

将pyx文件编译成pyd文件(很多坑,已解决)

项目场景: Faster R-CNN项目,将pyx文件编译成pyd文件(很多坑,请注意) 项目环境 python 3.6 – conda的虚拟环境 TensorFlow 1.15.0 win 10 问题描述 使用网上的教程进行编译 有一个需要被编译的bbox.pyx文件,创建…

python文件中import pyx文件问题

1、首先,pyx文件需要安装Cython,这里先进入自己的虚拟环境,用conda安装Cython conda install Cython 2、需要用到pyx的地方是mattnet中的mask.py 文件,里面 import _mask.pyx 文件,需要先在mask的目录下建立setup文…

成功解决windows下将.pyx文件编译成.pyd文件

在linux上正常跑通的算法,搬到windows下使用就报错了 原来是其中涉及到.pyx文件的编译 在linux下.pyx会被编译成.so的文件,但是在windows下是无法使用.so文件的 需要重新编译成windows下的.pyd格式的才可以直接将python模块成功导入到算法中 所以需要解…

.pyx文件编译出错

文章目录 .pyx文件的编译导入 参考博客(写的超级好,完美解决了问题) 错误 ImportError: Building module dtw failed: ["distutils.errors.CompileError: command D:\\\\Program Files (x86)\\\\Microsoft Visual Studio\\\\2019\\\\Pr…

python导入pyx文件失败

报错如下: 出现无法导入的情况时,在import之前加上一下两条语句即可解决问题: import pyximport pyximport.install()

pyx 编译成 pyd

1、编写好py文件,然后将后缀改为pyx 2、编写好setup.py文件 3、在setup.py 文件同目录下打开命令行执行: python setup.py build_ext --inplace之后就会生成pyd文件 和C文件 示例: 需要编译成pyd的文件 fast_fib.pyx import functoolsdef …

如何在pycharm上编译使用pyx文件

前言 cython是专门用来写在Python里面import用的扩展库。实际上Cython的语法基本上跟Python一致,而Cython有专门的“编译器”先将 Cython代码转变成C,然后使用C编译器编译出最终的Python可调用的模块。 本人因在github中找到了一份用cython写的自定义库…

虚拟机的安装与ubuntu的创建,,Ubuntu快捷键

文章目录 vmware安装包与Ubuntu镜像文件:VMware的安装Ubuntu的创建Ubuntu快捷键 在学习与工作中,我们往往可能需要用到windows以外的操作系统,比如Linux系统就适合开发者的使用,往往用到虚拟机,这篇博客来讲讲VMware的…

Ubuntu操作-09 快捷键

文章目录 1 系统快捷键2 终端快捷键3 Gedit编辑器快捷键 Ubuntu快捷键介绍,已在Ubuntu21.10测试 1 系统快捷键 命令说明Ctrl Alt Fn1进入图形化用户登录界面Ctrl Alt Fn2进入当前图形化界面Ctrl Alt Fn3-Fn6进入命令行虚拟终端Ctrl Alt Fn7-Fn12进入另外的…

不可不知的ubuntu系统快捷键

软硬件环境 ubuntu 19.10 64bit Desktop 前言 ubuntu是当前最流行的linux发行版之一,使用ubuntu除了经常使用的Ctrlc (复制) 和Ctrlv (粘帖),其实还有一些不常用但却很有用的快捷键,熟练掌握常用快捷键绝对可以大大提升你的工作学习效率。文中…

ubuntu系统的快捷键,软件等配置

最近要完全使用ubuntu桌面系统了,很多在win 上的快捷键和软件都无法使用了,这里打算总结一下。 文章目录 1 常用快捷键2 常用配置调整左侧状态栏的顺序截图火狐禁止通知键盘快捷键设置DNS修改默认打开程序vs code 终端间距太大 3 常用软件安装meshlabana…