多态、继承、this、super、及多态执行方法时的原理

先放一下多态的定义:

(360词典上的哈)

多态(Polymorphism)按字面的意思就是"多种状态"。在面向对象语言中,接口的多种不同的实现方式即为多态。引用Charlie Calverts对多态的描述--多态性是允许你将父对象设置成为一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作(摘自"Delphi4 编程技术内幕")。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针

看完上面的定义,可能你会觉得有点懵,其实也就是两句话:

1.一种事物的多种形态

2.父类引用指向子类对象

 

首先来解释第一点:

  多态是指的一种事务的多种形态。

说明一下抽象:

  抽象:忽略物体的实际属性的状态、个体的特殊行为等,忽略问题的表现,而关注问题的本质的一个过程。

比如说,我们每一个人都是一个个体。我们就可以把个体的特殊行为和特殊属性值忽略,而抽取每一个人的共性作为人这个类。

而我们实现对象的时候再把我们个体的这些特殊属性值为人这个类的属性赋值。而在类中,我们人这个类虽然有属性,却没有具体指。

为类的属性填值和改变具体行为的过程,被称为类的实现也就是建立一个对象。

简化为一句话哈(抽象是忽略个体实际而转化为一个类型的过程。实例化是将类型特殊化为一个个体的过程)

 

然后下一个概念是继承:(一定要理解昂)

  继承是将一个类型泛化为多个类型的过程,且子类型拥有(继承了)父类型所拥有的所有元素(所有非private类型的方法和变量)

  这句话的意思就是,这个类型又可以分为多个子类型,举个例子的话,人这个类型可以泛化为男人和女人这两个具体一点的类型。

 

首先说明一下上面的的继承所得到的东西:

我们之前的博文有讲到过类的加载机制,在static那一篇。

在一个对象的创建过程中的第二个阶段,指向非静态代码块和构造函数的时候我们也执行的父类的非静态代码块和构造函数函数,

这个过程是不是就表明,在创建一个类的时候,我们一定也会创建一个它所对应的父类(对于每个对象来说都是如此,所以其实Java创建一个对象,其实创建了好多个,显得特别臃肿)

而在我们每一个对象中都有一个super、this引用,super指向它的直接父类、this指向自己。(接下来会讲到)

类继承的时候会继承父类对象的的所有的非private修饰的成员变量和成员方法。

对于变量来说它实际上是把父类对象的可以继承的成员变量赋值了一份放在了自己这里。

但是对于成员变量来说则是各自有各自的区域,存储的是不同的成员变量,不过子类会拷贝一份父类的非private的成员变量。

对于方法来说,则不会继承父类的private成员方法,其它的方法子类继承了。但是如果自己写了一个除了方法体和父类的某个方法重名的方法(返回值类型可以不同,不过返回值类型必须是父类返回值类型的子类(多态)),则会覆盖父类的那个方法。

对于方法重写有两个注意事项:

子类的方法不能比父类的方法的访问权限小,抛出的异常不能比父类的大。(接下来讲)

 

接下来就该多态了:

我们说多态是一种事务的多种形态,其实就是说的我们的泛化,不过比泛化更具体一下,多态是,把泛化实例化了。就是把泛化的类型实例化了。

第二局是父类引用指向子类对象,则是多态的表现形式。它的意思是说,我们可以使用父类类型的引用指向子类类型的对象。(好好体会一下就懂了)

这就是多态了。用一种大类型来指向多种小类型,来描述事物类型之间的一种集合关系(同属于一种集合,但是又不是同一种类型,比如哺乳动物、人、狗狗)人和狗是哺乳动物的多种形态

 

接下来我们该说一下使用多态时应该注意的点。其实理解了上面的下面的就自己能想到了。

A 是父类  A1、A2是子类

A a = new A1()

使用多态时,调用(a.value)属性的时候,实际上是调用的a的父类型的属性,也就是A类型的,因为,人家会判断你的引用类型。

而使用a.str()方法时,则是使用的子类的方法,因为,在调用方法时,它不会去检查引用类型。直接调用的就是子类所拥有的方法。

对于静态方法和静态变量来说,则会检查引用类型。调用对应引用类型的类的静态变量和函数。(上面这三句话,一定要记住昂,除了方法之外,其它的都会检查引用类型)

 

讨论完继承、多态之后,我们还需要讨论一下this、super关键字。这个是在每个对象中都有的。

this是指向当前对象的一个引用,super是指向其父类对象的一个引用。

this()执行当前类的无参构造函数

super()执行父类的无参构造函数,

在类的无参构造函数的第一行默认调用了super()

this()\super()不能同时出现,原因自己想一下哦,我们总不可能初始化两次某个对象吧。

还有关于this、super的一个重要知识点,

this调用的是当前类的方法,super调用的也是它指向的父类的方法。(这里需要强调一下,虽然父类的方法被子类所覆盖的,但是这里指向的是父类的对象,所以是去父类的方法所存储的地方寻找对应的方法,而不是去this指向的子类的存储方法的地方寻找。我记得Java中的类的方法只有一份,我记得是这样啊,不是太确定。不过这个并不影响我们判断。寻找方法的时候是不判断引用类型,而是通过引用指向的对象,去这个对象的类型的方法集里找对应的,所以这里和子类的方法集无关,每一个类有一个方法集)

this 也用来分别成员变量和参数重名的情况

this 、super都不要在静态环境中使(变量、方法、代码块)用,他们都是在对象生成之后才有的

从本质上讲,this是一个指向本对象的指针,super是个关键字

super可以用来调用父类中被隐藏的方法和变量

super()必须卸载子类构造函数的第一行

this(参数)调用其它构造函数,也必须放在第一行

posted on 2019-08-11 23:41  暮城暮雪  阅读(613)  评论(0编辑  收藏  举报

导航