Java内功心法,深入解析面向对象

作者 : 开心源码 本文共4361个字,预计阅读时间需要11分钟 发布时间: 2022-05-13 共200人阅读

什么是对象
对象是系统中用来形容客观事物的一个实体,它是构成系统的一个基本单位。一个对象由一组属性和对这组属性进行操作的一组服务组成。

类的实例化可生成对象,一个对象的生命周期包括三个阶段:生成、使用、消除。

当不存在对一个对象的引用时,该对象成为一个无用对象。Java的垃圾收集器自动扫描对象的动态内存区,把没有引用的对象作为垃圾收集起来并释放。当系统内存用尽或者调用System.gc()要求垃圾回收时,垃圾回收程与系统同步运行。

面向对象的特征
封装,继承和多态。

封装:面向对象最基础的一个特性,封装性,是指隐藏对象的属性和现实细节,仅对外提供公共访问方式。
封装的准则:将不需要对外提供的内容都隐藏(设置访问修饰符为“private”)起来。把属性都隐藏,仅提供公共方法对其访问,可以在访问方式中加入逻辑判断等语句。
继承:继承是从已有类得到继承信息创立新类的过程。提供继承信息的类被称为父类(超类、基类);得到继承信息的类被称为子类(派生类)。
多态:多态性是指允许不同子类型的对象对同一消息作出不同的响应。简单的说就是用同样的对象引用调用同样的方法但是做了不同的事情。
多态性分为编译时的多态性和运行时的多态性。
运行时的多态是面向对象最精髓的东西,要实现多态需要做两件事:
1). 方法重写(子类继承父类并重写父类中已有的或者笼统的方法)
2). 对象造型(用父类型引用引用子类型对象,这样同样的引用调用同样的方法就会根据子类对象的不同而体现出不同的行为)。
什么是类
类是具备相同属性和方法的一组对象的集合,它为属于该类的所有对象提供了统一的笼统形容,其内部包括属性和方法两个主要部分。在面向对象的编程语言中,类是一个独立的程序单位,它应该有一个类名并包括属性和方法两个主要部分。

Java中的类实现包括两个部分:类公告和类体。

多态的好处
多态的定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。

主要有以下优点:

可替换性:多态对已存在代码具备可替换性.
可扩充性:添加新的子类不影响已经存在的类结构.
接口性:多态是超类通过方法签名,向子类提供一个公共接口,由子类来完善或者者重写它来实现的.
灵活性:它在应用中表现了灵活多样的操作,提高了使用效率
简化性:多态简化对应用软件的代码编写和修改过程,尤其在解决大量对象的运算和操作时,这个特点尤为突出和重要
代码中如何实现多态
实现多态主要有以下三种方式:

接口实现
继承父类重写方法
同一类中进行方法重载
虚拟机是如何实现多态的
动态绑定技术(dynamic binding),执行期间判断所引用对象的实际类型,根据实际类型调用对应的方法.

重载(Overload)和重写(Override)的区别。重载的方法是否根据返回类型进行区分?
方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,然后者实现的是运行时的多态性。

重载发生在一个类中,同名的方法假如有不同的参数列表(参数类型不同、参数个数不同或者者二者都不同)则视为重载;
重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的返回类型,比父类被重写方法更好访问,不能比父类被重写方法公告更多的异常(里氏代换准则)。重载对返回类型没有特殊的要求。
构造器不能被继承,因而不能被重写,但可以被重载。

父类的静态方法不能被子类重写。重写只适用于实例方法,不能用于静态方法,而子类当中含有和父类相同签名的静态方法,我们一般称之为隐藏,调用的方法为定义的类所有的静态方法。

构造器(constructor)能否可被重写(override)?
构造器不能被继承,因而不能被重写,但可以被重载。

接口的意义
接口的意义用四个词即可以概括:规范,扩展,回调和安全。

笼统类的意义
笼统类的意义可以用三句话来概括:

为其余子类提供一个公共的类型
封装子类中重复定义的内容
定义笼统方法,子类尽管有不同的实现,但是定义是一致的
笼统类和接口有什么区别
笼统类和接口都不能够实例化,但可以定义笼统类和接口类型的引用。一个类假如继承了某个笼统类或者者实现了某个接口都需要对其中的笼统方法一律进行实现,否则该类依然需要被公告为笼统类。接口比笼统类更加笼统,由于笼统类中可以定义构造器,可以有笼统方法和具体方法,而接口中不能定义构造器而且其中的方法一律都是笼统方法。笼统类中的成员可以是private、默认、protected、public的,而接口中的成员全都是public的。笼统类中可以定义成员变量,而接口中定义的成员变量实际上都是常量。有笼统方法的类必需被公告为笼统类,而笼统类未必要有笼统方法。

访问修饰符public,private,protected,以及不写(默认)时的区别
修饰符当前类同包子类其余包public√√√√protected√√√×default√√××private√×××

类的成员不写访问修饰时默认为default。默认对于同一个包中的其余类相当于公开(public),对于不是同一个包中的其余类相当于私有(private)。受保护(protected)对子类相当于公开,对不是同一包中的没有父子关系的类相当于私有。Java中,外部类的修饰符只能是public或者默认,类的成员(包括内部类)的修饰符可以是以上四种。

简述一下面向对象的”六准则一法则”。
单一职责准则:一个类只做它该做的事情。
单一职责准则想表达的就是”高内聚”,写代码最终极的准则只有六个字”高内聚、低耦合”。所谓的高内聚就是一个代码模块只完成一项功能,在面向对象中,假如只让一个类完成它该做的事,而不涉及与它无关的领域就是践行了高内聚的准则,这个类就只有单一职责。我们都知道一句话叫”由于专注,所以专业”,一个对象假如承担太多的职责,那么注定它什么都做不好。一个好的软件系统,它里面的每个功能模块也应该是可以轻易的拿到其余系统中使用的,这样才能实现软件复用的目标。

开闭准则:软件实体应当对扩开展放,对修改关闭。
在理想的状态下,当我们需要为一个软件系统添加新功能时,只要要从原来的系统派生出少量新类即可以,不需要修改原来的任何一行代码。要做到开闭有两个要点:

1)笼统是关键,一个系统中假如没有笼统类或者接口系统就没有扩展点;

2)封装可变性,将系统中的各种可变因素封装到一个继承结构中,假如多个可变因素混杂在一起,系统将变得复杂而换乱,假如不清楚如何封装可变性,可以参考《设计模式精解》一书中对桥梁模式的讲解的章节。

依赖倒转准则:面向接口编程。
该准则说得直白和具体少量就是公告方法的参数类型、方法的返回类型、变量的引用类型时,尽可能使用笼统类型而不用具体类型,由于笼统类型可以被它的任何一个子类型所替代,请参考下面的里氏替换准则。

里氏替换准则:任何时候都可以用子类型替换掉父类型。
关于里氏替换准则的形容,Barbara Liskov女士的形容比这个要复杂得多,但简单的说就是能用父类型的地方就肯定能使用子类型。里氏替换准则可以检查继承关系能否正当,假如一个继承关系违反了里氏替换准则,那么这个继承关系肯定是错误的,需要对代码进行重构。例如让猫继承狗,或者者狗继承猫,又或者者让正方形继承长方形都是错误的继承关系,由于你很容易找到违背里氏替换准则的场景。需要注意的是:子类肯定是添加父类的能力而不是减少父类的能力,由于子类比父类的能力更多,把能力多的对象当成能力少的对象来用当然没有任何疑问。

接口隔离准则:接口要小而专,绝不能大而全。
臃肿的接口是对接口的污染,既然接口表示能力,那么一个接口只应该形容一种能力,接口也应该是高度内聚的。例如,琴棋书画就应该分别设计为四个接口,而不应设计成一个接口中的四个方法,由于假如设计成一个接口中的四个方法,那么这个接口很难用,毕竟琴棋书画四样都精通的人还是少数,而假如设计成四个接口,会几项就实现几个接口,这样的话每个接口被复用的可能性是很高的。Java中的接口代表能力、代表商定、代表角色,是否正确的使用接口肯定是编程水平高低的重要标识。

合成聚合复用准则:优先使用聚合或者合成关系复用代码。
通过继承来复用代码是面向对象程序设计中被滥用得最多的东西,由于所有的教科书都无一例外的对继承进行了鼓吹从而误导了初学者,类与类之间简单的说有三种关系,Is-A关系、Has-A关系、Use-A关系,分别代表继承、关联和依赖。

其中,关联关系根据其关联的强度又可以进一步划分为关联、聚合和合成,但说白了都是Has-A关系,合成聚合复用准则想表达的是优先考虑Has-A关系而不是Is-A关系复用代码,起因嘛可以自己从百度上找到一万个理由,需要说明的是,即便在Java的API中也有不少滥用继承的例子,例如Properties类继承了Hashtable类,Stack类继承了Vector类,这些继承显著就是错误的,更好的做法是在Properties类中放置一个Hashtable类型的成员并且将其键和值都设置为字符串来存储数据,而Stack类的设计也应该是在Stack类中放一个Vector对象来存储数据。记住:任何时候都不要继承工具类,工具是可以拥有并可以使用的,而不是拿来继承的。

迪米特法则:迪米特法则又叫最少知识准则,一个对象应当对其余对象有尽可能少的理解。
迪米特法则简单的说就是如何做到”低耦合”,门面模式和调停者模式就是对迪米特法则的践行。对于门面模式可以举一个简单的例子,你去一家公司洽谈业务,你不需要理解这个公司内部是如何运作的,你甚至可以对这个公司一无所知,去的时候只要要找到公司入口处的前端美女,告诉她们你要做什么,她们会找到合适的人跟你接洽,前端的美女就是公司这个系统的门面。

再复杂的系统都可以为客户提供一个简单的门面,Java Web开发中作为前台控制器的Servlet或者Filter不就是一个门面吗,浏览器对服务器的运作方式一无所知,但是通过前台控制器就能够根据你的请求得到相应的服务。

调停者模式也可以举一个简单的例子来说明,例如一台计算机,CPU、内存、硬盘、显卡、声卡各种设施需要相互配合才能很好的工作,但是假如这些东西都直接连接到一起,计算机的布线将异常复杂,在这种情况下,主板作为一个调停者的身份出现,它将各个设施连接在一起而不需要每个设施之间直接交换数据,这样就减小了系统的耦合度和复杂度。

本人免费整理了Java高级资料,涵盖了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo高并发分布式等教程,一共30G,需要自己领取。
传送门:https://mp.weixin.qq.com/s/JzddfH-7yNudmkjT0IRL8Q

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Java内功心法,深入解析面向对象

发表回复