java四大特性理解(封装继承多态抽象)JAVA之迷

封装是把过程和数据包围起来,对数据的访问只能通过已定义的接口。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。封装是一种信息隐藏技术,在java中通过关键字private实现封装。什么是封装?封装把对像的所有组成部分组合在一起,封装定义程序如何引用对象的数据,封装实际上使用方法将类的数据隐藏起来,控制用户对类的修改和访问数据的程度。

什么是多态

下面是多态存在的三个必要条件,要求大家做梦时都能背出来!

多态存在的三个必要条件一、要有继承;二、要有重写;三、父类引用指向子类对象。

多态的好处:

1.可替换性(substitutability)。多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。2.可扩充性(extensibility)。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。3.接口性(interface-ability)。多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。如图8.3所示。图中超类Shape规定了两个实现多态的接口方法,computeArea()以及computeVolume()。子类,如Circle和Sphere为了实现多态,完善或者覆盖这两个接口方法。4.灵活性(flexibility)。它在应用中体现了灵活多样的操作,提高了使用效率。5.简化性(simplicity)。多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。

Java中多态的实现方式:接口实现,继承父类进行方法重写,同一个类中进行方法重载。

Java中的继承、封装、多态

继承的理解:

1、继承是面向对象的三大特征之一,也是实现代码复用的重要手段。Java的继承具有单继承的特点,每个子类只有一个直接父类。

2、Java的继承通过extends关键字来实现,实现继承的类被称为子类,被继承的类称为父类(有的也称其为基类、超类),父类和子类的关系,是一种一般和特殊的关系。就像是水果和苹果的关系,苹果继承了水果,苹果是水果的子类,水果是苹果的父类,则苹果是一种特殊的水果。

3、Java使用extends作为继承的关键字,extends关键字在英文是扩展的意思,而不是继承。为什么国内把extends翻译成继承呢?除了与历史原因有关外,把extends翻译成为继承也是有其道理的:子类扩展父类,将可以获得父类的全部属性和方法,这与汉语中得继承(子辈从父辈那里获得一笔财富成为继承)具有很好的类似性。值得指出的是:Java的子类不能获得父类的构造器。

4、实例:

classBaseClass{

publicdoubleweight;

publicvoidinfo(){

System.out.println("我的体重是"+weight+"千克");

}

publicclassExtendsDemo001extendsBaseClass{

publicstaticvoidmain(String[]args){

//创建ExtendsDemo001对象

ExtendsDemo001ed=newExtendsDemo001();

//ExtendsDemo001本身没有weight属性,但是ExtendsDemo001的父类有weight属性,也可以访问ExtendsDemo001对象的属性

ed.weight=56;

//调用ExtendsDemo001对象的info()方法

ed.info();

打印结果为:我的体重是56.0千克

5、Java类只能有一个父类。这句话是错误的,应该这样说:Java类只能有一个直接父类,可以有无限多个间接父类,如:

classFruitextendsPlant{…….}

classAppleextendsFruit{…….}

重写父类的方法:

1、大部分的时候,子类总是以父类为基础,额外添加新的属性和方法。但有一种情况例外:子类需要重写父类的方法。例如鸟类都包含了飞翔的方法,其中鸵鸟是一种特殊的鸟类,因此鸵鸟也是鸟的子类,因此它也将从鸟类获得飞翔方法,但这个飞翔方法明显不适合鸵鸟,为此,鸵鸟需要重写鸟类的方法。

2、如下代码可以帮助理解重写:

1)classBird{

2)//Bird类的fly()方法

3)privatevoidfly(){

4)System.out.println("我要在天空中飞翔");

5)}

6)}

7)publicclassOcerrideTestextendsBird{

8)//重写Bird类的fly()方法

9)publicvoidfly(){

10)System.out.println("我只能在地上奔跑");

11)}

12)publicstaticvoidmain(String[]args){

13)//创建OcerrideTest对象

14)OcerrideTestot=newOcerrideTest();

15)ot.fly();

16)}

17)}

打印结果为:我只能在地上奔跑

这种子类包含父类同名方法的现象被称为方法重写,也被称为方法覆盖(Override)。

方法的重写要遵循“两同两小一大”规则:

⑴“两同”:方法名相同;形参列表相同。

⑶子类方法的访问权限应比父类方法更大或相等

尤其需要指出的是:覆盖方法和被覆盖方法要么都是类方法,要么都是实例方法,不能一个是类方法,一个是实例方法,例如下面的代码将会有编译错误:

ClassBaseClass{

publicstaticvoidtest(){…….}

ClassSubClassextendsBaseClass{

publicvoidtest(){………….}

若想调用父类中的fly()方法,则只需在子类中fly()方法中加上如下代码即可:

super.fly();

注意:super和this一样,都不能出现在static的方法中

调用父类构造器

1、看如下程序定义的BaseheSub类,其中Sub类是Base类的子类,程序在Sub类的构造器中使用super来调用Base构造器里的初始化代码。

classBase{

publicdoublesize;

publicStringname;

publicBase(doublesize,Stringname){

this.size=size;

this.name=name;

publicclassSubextendsBase{

publicStringcolor;

publicSub(doublesize,Stringname,Stringcolor){

//在子类构造器中调用父类构造器,使用super调用来实现

super(size,name);

this.color=color;

Subs=newSub(5.6,"测试对象","红色");

System.out.println(s.size+"------"+s.name+"------"+s.color);

打印结果为:5.6------测试对象------红色

静态初始化块

封装的理解:

1、封装(Encapsulation)是面向对象的三大特征之一,它指的是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问。

2、掌握了访问控制符的用法之后,下面通过使用合理的访问控制来定义一个Person类,这个Person类就实现了良好的封装。代码如下:

publicclassPerson{

Personp=newPerson();

p.setAge(10);

System.out.println(p.getAge());

//将属性使用private修饰,将这些属性隐藏起来

privateStringname;

privateintage;

//提供方法来操作name属性

publicvoidsetName(Stringname){

//对姓名执行合理的校验

if(name.length()>6||name.length()<2){

System.out.println("您的姓名不符合要求");

}else{

publicStringgetName(){

returnthis.name;

//提供方法来操作age属性

publicvoidsetAge(intage){

if(age>100||age<0){

System.out.println("您的年龄必须要在0~100之间");

this.age=age;

publicintgetAge(){

returnthis.age;

运行结果为:10

多态的理解:

1、多态(Polymorphism)是面向对象的三大特征之一。

先看下面的程序:

classSuperClass{

publicintbook=6;

publicvoidbase(){

System.out.println("父类的普通方法base()");

publicvoidtest(){

System.out.println("父类中北覆盖的方法");

publicclassPloymorphismTest001extendsSuperClass{

//重新定义一个book实例属性,覆盖父类的book实例属性

publicStringbook="Java疯狂讲义";

System.out.println("子类中覆盖父类的方法");

privatevoidDmeo(){

System.out.println("子类中普通的方法");

//主方法

//下面编译时类型和运行时类型完全一样,因此不存在多态

SuperClasssc=newSuperClass();

System.out.println("book1="+sc.book);//打印结果为:6

//下面两次调用将执行SuperClass的方法

sc.base();

sc.test();

PloymorphismTest001pt=newPloymorphismTest001();

System.out.println("book2="+pt.book);//打印结果为:Java疯狂讲义

//下面调用将执行从父类继承到的base方法

pt.base();

//下面调用将执行当前类的test方法

pt.test();

//下面编译时类型和运行时类型不一样,多态发生

SuperClasssscc=newPloymorphismTest001();

//结果表明访问的是父类属性

System.out.println("book3="+sscc.book);//打印结果为:6

//下面调用将执行从父类继承到得base方法

sscc.base();

sscc.test();

//因为sscc的编译类型是SuperClass,SuperClass类没有提供Demo()方法

//所以下面代码编译时会出现错误

//sscc.Demo();

程序运行结果为:

book1=6

父类的普通方法base()

父类中北覆盖的方法

book2=Java疯狂讲义

子类中覆盖父类的方法

book3=6

上面程序的main方法中显示创建而来3个引用变量,对于前两个引用变量sc和pt,它们编译时类型和运行时类型完全相同,因此调用它们的属性和方法非常正常,完全没有问题。但第三个引用变量sscc,则比较特殊,它编译时类型是SuperClass,而运行时类型是PloymorphismTest001,当调用该引用变量的test方法时,实际上是执行PloymorphismTest001类中覆盖后的test方法,这就是多态。

当把一个子类对象直接赋给父类引用变量,例如上面的SuperClasssscc=newPloymorphismTest001();这个sscc引用变量的编译时类型是SuperClass,而运行时类型是PloymorphismTest001,当运行时调用该引用变量的方法时,其方法行为总是像子类方法的行为,而不是像父类方法行为,这将出现相同类型的变量、执行同一个方法时呈现出不同的行为特征,这就是多态。

特别提醒:

与方法不同的是,对象的属性则不具备多态性,如上面的sscc引用变量,程序中输出它的book属性时,并不是输出PloymorphismTest001类里定义的实例属性,而是输出SuperClass类的实例属性。

注意:

我们通过Objectp=newPerson()代码定义一个变量p,则这个p只能调用Object类的方法,而不能调用Person类里定义的方法。

在没有好好地研习面向对象设计的设计模式之前,我对Java接口和Java抽象类的认识还是很模糊,很不可理解。

刚学Java语言时,就很难理解为什么要有接口这个概念,虽说是可以实现所谓的多继承,可一个只有方法名,没有方法体的东西,我实现它又有什么用呢?我从它那什么也得不到,除了一些方法名,我直接在具体类里加入这些方法不就行了吗?

为什么一定要有抽象类这个概念?为什么就不能把这个父类写成一个具体的类,子类再继承它不就可以了吗?何必弄一个抽象类出来,还要弄一些没有方法体的抽象方法,弄得又象接口又象类的,让人捉摸不定。

当我开始学习java设计模式,真正走进面向对象设计的大门之后,我才发现,自己对面向对象设计的理解原来是那么的片面,那么的肤浅,根本就没有真正理解面向对象思想的精髓,在某一种程度上还受着面向过程的影响,以为弄出了一个个类,就算是面向对象了,而其实还是被过程所驱使着。

我还是说说我现在对面向对象思想的理解吧,不一定正确全面,但我想应该还算是比以前略有进步吧。

面向对象思想,我觉得最关键的就是抽象。

一个软件设计的好坏,我想很大程度上取决于它的整体架构,而这个整体架构其实就是你对整个宏观商业业务的抽象框架,当代表业务逻辑的高层抽象层结构合理时,你底层的具体实现需要考虑的就仅仅是一些算法和一些具体的业务实现了。当你需要再开发另一个相近的项目时,你以前的抽象层说不定还可以再次利用呢,面对对象的设计,复用的重点其实应该是抽象层的复用,而不是具体某一个代码块的复用,是不是一下子感觉自己对复用理解的高度又上升了一层?^_^

说到了抽象,我就不能不提到曾让我头痛的Java接口和Java抽象类了,这也是本文我想说的重点。

既然面向对象设计的重点在于抽象,那Java接口和Java抽象类就有它存在的必然性了。

Java接口和Java抽象类代表的就是抽象类型,就是我们需要提出的抽象层的具体表现。OOP面向对象的编程,如果要提高程序的复用率,增加程序的可维护性,可扩展性,就必须是面向接口的编程,面向抽象的编程,正确地使用接口、抽象类这些太有用的抽象类型做为你结构层次上的顶层。

Java接口和Java抽象类有太多相似的地方,又有太多特别的地方,究竟在什么地方,才是它们的最佳位置呢?把它们比较一下,你就可以发现了。

1、Java接口和Java抽象类最大的一个区别,就在于Java抽象类可以提供某些方法的部分实现,而Java接口不可以,这大概就是Java抽象类唯一的优点吧,但这个优点非常有用。如果向一个抽象类里加入一个新的具体方法时,那么它所有的子类都一下子都得到了这个新方法,而Java接口做不到这一点,如果向一个Java接口里加入一个新方法,所有实现这个接口的类就无法成功通过编译了,因为你必须让每一个类都再实现这个方法才行,这显然是Java接口的缺点。

2、一个抽象类的实现只能由这个抽象类的子类给出,也就是说,这个实现处在抽象类所定义出的继承的等级结构中,而由于Java语言的单继承性,所以抽象类作为类型定义工具的效能大打折扣。在这一点上,Java接口的优势就出来了,任何一个实现了一个Java接口所规定的方法的类都可以具有这个接口的类型,而一个类可以实现任意多个Java接口,从而这个类就有了多种类型。

3、从第2点不难看出,Java接口是定义混合类型的理想工具,混合类表明一个类不仅仅具有某个主类型的行为,而且具有其他的次要行为。

Java接口和Java抽象类的存在就是为了用于具体类的实现和继承的,如果你准备写一个具体类去继承另一个具体类的话,那你的设计就有很大问题了。Java抽象类就是为了继承而存在的,它的抽象方法就是为了强制子类必须去实现的。

我想,如果你编的代码里面连一个接口和抽象类都没有的话,也许我可以说你根本没有用到任何设计模式,任何一个设计模式都是和抽象分不开的,而抽象与Java接口和抽象Java类又是分不开的。

理解抽象,理解Java接口和抽象Java类,我想就应该是真正开始用面向对象的思想去分析问题,解决问题了吧。

THE END
1.从JDK8飞升到JDK17,再到未来的JDK21/*** 定义一个抽象密封类Pet,它的实现类只能是Dog, Cat这两个,其他的实现类均不允许*/publicabstractsealedclassPetpermitsDog,Cat{}finalclassDogextendsPet{}finalclassCatextendsPet{}//密封的类和接口限制了其他类或接口可以扩展或实现它们publicsealedinterfaceShape{finalclassPlanetimplementsShape{}final...https://developer.aliyun.com/article/1084638
1....练习:实现一个接口并使用不同的实现类来展示多态的效果首先,我们定义一个接口PaymentMethod,它包含一个方法pay。 // 定义接口 PaymentMethod interfacePaymentMethod{ voidpay(doubleamount);// 支付方法,接受一个金额参数 } 2. 实现接口的类 接下来,我们定义几个实现了PaymentMethod接口的类,分别代表不同的支付方式。 https://blog.csdn.net/thinking_chou/article/details/143758931
2.Shape接口(Microsoft.Office.Interop.Word)MicrosoftLearn确定在调整形状大小时是否可以彼此独立地更改形状的高度和宽度,或者它是否保留其原始比例。 Name 返回或设置指定对象的名称。 Nodes 返回一个 ShapeNodes 集合,该集合表示指定形状的几何说明。 OLEFormat 返回一个 OLEFormat 对象,该对象表示 OLE 特征 (指定形状的链接) 。 Parent 返回一个对象,代表指定对象的父对象...https://technet.microsoft.com/zh-cn/library/microsoft.office.interop.word.shape(v=office.11).aspx
3.JAVA篇之类和对象编程语言Java是一门面向对象的编程语言(Object Oriented Program,简称OOP),面向对象编程的核心思想是将数据(属性)和操作数据的方法封装成一个整体,即对象。对象之间通过信息传递来相互协作,从而实现特定的功能。 1.1 面向对象和面向过程 面向过程注重解决问题的步骤和操作,面向对象是把构成问题事务分解成各个对象,建立对象的目的...http://www.licqi.com/artikel/24239.html
4.设计一个名为Rectangle的类表示矩形。这个类包括:(1)两个名为...设计一个名为Swimmable的接口,其中包含void swim()方法。设计另一个名为Flyable的接口,其中包含void fly()方法。定义一个Duck类实现上述两个接口。定义测试类,演示接口类型的使用。 设计一个名为Swimmable的接口,其中包含void swim()方法。设计另一个名为Flyable的接口,其中包含void fly()方法。定义一个Duck类实现...https://www.xuesai.cn/souti/IY2DSDTI.html
5.Java中抽象类和接口的用法详解java在Java中,接口可以看成是:多个类的公共规范,是一种引用数据类型。 Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。 接口可以理解为一种特殊的类,里面全部是由全局常量和公共的抽象方法...https://www.jb51.net/article/259951.htm
6.强化学习八股文温柔一刀的技术博客设计模式的分类 1. 创建型模式 1. 单例模式(一个实例) 2. 工厂模式(工厂提供创建类的方法) 3. 抽象工厂模式(抽象工厂接口,要有实现具体工厂类) 4. 建造者模式(xxxBuilder、是特定的类) 1. 指挥者Director 1. 有个Builder对象() 2. 有个执行组装builder的方法 3. 有个获取Computer的方法(getComputer) ...https://blog.51cto.com/u_14120/12566685
7.Alibaba最新1000多道Java面试题汇总详解,收藏起来慢慢刷!33、接口是否可继承(extends)接口?抽象类是否可实现(implements)接口?抽象类是否可继承具体类(concreteclass)? 34、一个”.java”源文件中是否可以包含多个类(不是内部类)?有什么限制? 35、Java 中的 final 关键字有哪些用法? 二、Java 集合/泛型面试题 ...https://maimai.cn/article/detail?fid=1728969401&efid=esjJLvGGL4fAr1LArgq_cQ
8.一篇文章入门多物理场有限元(全篇)按照面向对象设计方法,可以设计出四个接口基类;按照阶数来分,至少有0阶,1阶和2阶,阶数可以作为属性放在实现类中;引入自由度,单元设计会稍微复杂一点,每个节点自由度根据特定单元类型不同而不同,比如有些节点只考虑平动,不考虑转动,有些节点只考虑磁场不考虑电场;再引入多物理场,单元设计会更加复杂,以三维四面体单元...http://www.360doc.com/content/22/1204/22/80945647_1058861009.shtml
9.使用Spyder进行财务数据分析—Spyder5文档它有很好的绘图库 您可以使用资源,例如 Google Colab 或Binder 在云中进行分析。 我为什么要使用IDE? 虽然您可以在没有IDE(集成开发环境)的情况下使用Python,但是使用IDE(集成开发环境)会更好。Spyder是一个用Python编写的科学集成开发环境,由科学家、工程师和数据分析师设计。Spyder的功能及其与Python的集成使其成为...https://www.osgeo.cn/spyder-docs/workshops/financial.html
10.下一节:第10章python程序开发基础在Python的发展过程中,形成了Python 2.x和Python 3.x两个不同系列的版本,Python 3.x版本相对于Python 2.x版本,是一个较大的升级,Python 3.x在设计的时候没有考虑向下兼容,为了满足不同Python用户的需求,目前是Python 2.x和Python 3.x两个版本并存。2020年1月1日,官方宣布停止Python 2的更新,Python 2.7被...https://cloud.tencent.com/edu/learning/course-3080-56796
11.局域网技术实训IEEE802标准所描述的局域网参考模型对应于OSI参考模型的数据链路层和物理层,它将数据链路层划分为两个子层:逻辑链路控制子层(LLC)和介质控制子层(MAC)。 ? MAC子层是数据链路层的一个功能子层,主要制定管理和分配信道的协议规范。 ? LLC也是数据链路层的一个功能子层,它在MAC子层的支持下向网络层提供服务...http://www.zzxxjs.net/gzsjs/yygzs/kcjs/01/2535.shtml