多态

多态:是具有表现多种形态能力的特征。更专业的说法就是:同一个实现接口,不同的实例而执行不同的操作。

 

对象具有两种类型:

1):编译类型: 声明对象变量的类型 Animal表示把对象看出什么类型

2):运行类型: 对象的真实类型 Dog.运行类型一→对象的真实类型.

编译运行必须和运行类型的父类或相同

当编译运行和运行类型不同的时候,多态就出现了

所谓多态对象具有多种形态,对象可以存在不同的形式

Animal a = new Dog();   // a此时表示Dog类型的形态

  a = new Cat(); // a 此时表示Cat 类型的形态

多态的前提可以是继承关系(类和类) / 也可以是实现关系(接口和实现类). 在开发中多态一般都是第二种.

多态的特点把子类对象赋给父类变量,在运行时期会表现出具体的子类特征.(调用子类方法)

 

 

多态的好处:

把不同的子类对象都当做父类类型来看待,可以屏蔽不同子类对象之间的实现差异,从而写出通用的代码达到通用编程,以适应需求的不断变化.

 

 

多态方法调用问题

  多态时方法调用问题:

  前提:       必须先存在于多态情况.

 

  测试:  父类 Animal  子类Dog  方法eat;

  测试代码:

  Animal up = new Dog();  //多态

  Up.eat();  //输出什么结果?

情况一: eat方法存在于Animal(父类) 中,不存在于Dog(子类)中;

 

此时执行结果:编译通过,执行Animal的eat方法.

应该先从Dog 类中去找eat方法,找不到再去父类Animal中查找.

 

情况二:eat方法存在于Dog(子类)中,不存在与 Animal(父类) 中

此时执行结果:编译错误,

编译时期:会去编译类型(Animal)中找是否有eat方法;

找  到:编译通过,

找不到:编译报错.

情况三:eat方法 即存在于Animal(父类) 中 也存在于Dog(子类)中.

执行结果:

此时执行结果:编译通过,执行Dog的eat方法.

在运行时期,调用运行类Dog(子类) 中的方法.

 

情况三:eat方法 即存在于Animal(父类) 中 也存在于Dog(子类)中.但是eat是静态方法

此时这种情况,称之为隐藏,而不叫覆盖

 

此时执行结果:编译通过,执行Animal的eat方法.

静态方法的调用只需要类即可,

如果使用对象来调用静态方法,其实使用的是对象的编译类型来调用静态方法

和对象没有关系.

 

引用类型转换

引用类型的转换:

引用类型的大和小,指的是父类和子类的关系

自动类型转换:把子类对象赋给父类变量(多态)

Animal a = new Dog();

Object是所有类的根类;

Object obj = new Dog();  //此时是成立的,但是obj能调用Dog类里面的方法吗?  不能,因为在Object类中没有Dog类方法,所有编译报错

 

 

强制类型转换:把一个父类类型的对象赋给子类类型的变量.(但是该父类类型变量的真实类型是子类类型)

Animal a = new Dog();

Dog b = (Dog) a ;

 

Instanceof 运算符 : 判断该对象是否是一个类的实例.

语法格式: booelan b = 对象A  instanceof  类B  //判断A对象是否是B类的实例,如果是,返回true,否则返回false.

 

 

组合关系

继承关系:子类可以继承父类中部分的成员,那么此时子类是可以修改到父类的信息的

继承关系破坏封装,为了复用代码可能会让子类具有不该有的功能.

---------------------------------------------

为什么引入进程:为了代码复用

解决代码复用问题:不一定非要使用继承,也可以使用包含关系(has a )

一. 继承关系(破坏封装)

 

 

二.组合关系(类与对象的关系)

 

如果A类为了得到B类的功能行为:

如果A类是B类的一种特殊情况,我们就应该采用继承关系来实现.

 

否则使用组合体.

 

字段不存在多态特征

通过对象调用字段,在编译时期就已经决定了调用那一块内存空间的数-----因为:字段不存在覆盖的概念,在多态时,不能有多态特征(在运行时期体现子类特征).

当子类和父类存在相同的字段的时候,无论修饰是什么(即使是private),都会在各自的类空间中储存数据.

 

posted on 2017-12-21 14:24  听风醉  阅读(178)  评论(0编辑  收藏  举报

导航

因为不可能,所以才值得相信。